2013-05-10 01:37:14 +00:00
|
|
|
/* packet-ptpip.c
|
|
|
|
* Routines for PTP/IP (Picture Transfer Protocol) packet dissection
|
|
|
|
* 0xBismarck 2013
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-12 11:23:27 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2013-05-10 01:37:14 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* References:
|
|
|
|
* [1] CIPA DC-X005-2005 - PTP-IP
|
|
|
|
* [2] BS ISO 15740:2008 - Photography Electronic still picture imaging - Picture transfer protocol (PTP)
|
|
|
|
* for digital still photography devices
|
|
|
|
* [3] gPhoto's Reversed Engineered PTP/IP documentation - http://gphoto.sourceforge.net/doc/ptpip.php
|
|
|
|
* [4] gPhoto's ptp2 header file https://gphoto.svn.sourceforge.net/svnroot/gphoto/trunk/libgphoto2/camlibs/ptp2/ptp.h
|
|
|
|
*
|
2013-11-25 16:57:43 +00:00
|
|
|
* @todo: This is being written as 1 dissector when in reality there is PTP/IP and PTP.
|
|
|
|
* Future work should include splitting this into 2 so that the PTP layer may be used again for PTP/USB.
|
2013-05-10 01:37:14 +00:00
|
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <epan/packet.h>
|
2015-05-23 02:43:53 +00:00
|
|
|
#include <epan/prefs.h>
|
2013-11-25 16:57:43 +00:00
|
|
|
#include "packet-ptpip.h"
|
2013-05-10 01:37:14 +00:00
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* Define */
|
|
|
|
#define PTPIP_PORT 15740 /* [1] Section 2.2.3.1 */
|
|
|
|
#define PTPIP_GUID_SIZE 16 /* [1] Section 2.3.1 */
|
|
|
|
#define PTPIP_MAX_PARAM_COUNT 5 /* [1] Section 2.3.6 */
|
2013-05-10 01:37:14 +00:00
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* trees */
|
2013-05-10 01:37:14 +00:00
|
|
|
static gint ett_ptpIP = -1;
|
|
|
|
static gint ett_ptpIP_hdr = -1;
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* PTP/IP Fields */
|
2013-05-10 01:37:14 +00:00
|
|
|
static int proto_ptpIP = -1;
|
2013-11-25 16:57:43 +00:00
|
|
|
static int hf_ptpIP_len = -1; /* [1] Section 2.3 */
|
|
|
|
static int hf_ptpIP_pktType = -1; /* [1] Section 2.3 */
|
2013-05-10 01:37:14 +00:00
|
|
|
static int hf_ptpIP_guid = -1;
|
|
|
|
static int hf_ptpIP_name = -1;
|
|
|
|
static int hf_ptpIP_version = -1;
|
|
|
|
static int hf_ptpIP_connectionNumber = -1;
|
|
|
|
static int hf_ptpIP_dataPhaseInfo = -1;
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* note: separating the fields to make it easier to divide this code later. */
|
2013-05-10 01:37:14 +00:00
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* PTP Fields */
|
|
|
|
/* picking hf_ptp for now. Might need to change later for namespace issues with Precision Time Protocol. */
|
2013-05-10 01:37:14 +00:00
|
|
|
static int hf_ptp_opCode = -1;
|
2015-05-23 02:43:53 +00:00
|
|
|
static int hf_ptp_vendor_opCode = -1;
|
2013-05-10 01:37:14 +00:00
|
|
|
static int hf_ptp_respCode = -1;
|
2015-05-23 02:43:53 +00:00
|
|
|
static int hf_ptp_vendor_respCode = -1;
|
2013-05-10 01:37:14 +00:00
|
|
|
static int hf_ptp_eventCode = -1;
|
|
|
|
static int hf_ptp_transactionID = -1;
|
|
|
|
static int hf_ptp_totalDataLength = -1;
|
|
|
|
static int hf_ptp_opCode_param_sessionID = -1;
|
|
|
|
|
|
|
|
/* function declarations */
|
|
|
|
static int dissect_ptpIP (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_);
|
2013-11-25 16:57:43 +00:00
|
|
|
void dissect_ptpIP_init_command_request (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_init_command_ack (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_init_event_request (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_init_event_ack ( packet_info *pinfo);
|
|
|
|
void dissect_ptpIP_operation_request (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_operation_response (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_start_data (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_data (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_end_data (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_event (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_unicode_name (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_protocol_version (tvbuff_t *tvb, proto_tree *tree, guint16 *offset);
|
|
|
|
void dissect_ptpIP_guid (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset);
|
2013-05-10 01:37:14 +00:00
|
|
|
void proto_register_ptpip( void );
|
|
|
|
void proto_reg_handoff_ptpIP( void );
|
|
|
|
|
2015-05-23 02:43:53 +00:00
|
|
|
typedef enum {
|
|
|
|
PTP_VENDOR_UNKNOWN = 0,
|
|
|
|
PTP_VENDOR_EASTMAN_KODAK = 1,
|
|
|
|
PTP_VENDOR_CANON = 2,
|
|
|
|
PTP_VENDOR_NIKON = 3,
|
|
|
|
PTP_VENDOR_CASIO = 4,
|
|
|
|
PTP_VENDOR_MTP = 5,
|
|
|
|
PTP_VENDOR_OLYMPUS = 6
|
|
|
|
} ptp_vendors;
|
|
|
|
|
|
|
|
static const enum_val_t pref_hsp_role[] = {
|
|
|
|
{ "Unknown", "Unknown vendor", PTP_VENDOR_UNKNOWN },
|
|
|
|
{ "Eastman Kodak", "Eastman Kodak", PTP_VENDOR_EASTMAN_KODAK},
|
|
|
|
{ "Canon", "Canon", PTP_VENDOR_CANON },
|
|
|
|
{ "Nikon", "Nikon", PTP_VENDOR_NIKON },
|
|
|
|
{ "Casio", "Casio EX-F1", PTP_VENDOR_CASIO },
|
|
|
|
{ "Microsoft / MTP","Microsoft / MTP", PTP_VENDOR_MTP },
|
|
|
|
{ "Olympus", "Olympus E series", PTP_VENDOR_OLYMPUS },
|
|
|
|
{ NULL, NULL, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Vendor preference for deciphering opcodes */
|
|
|
|
static int pref_vendor = 0;
|
|
|
|
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
static const value_string ptp_opcode_names[] = {
|
|
|
|
{ PTP_OC_GetDeviceInfo, "GetDeviceInfo" },
|
|
|
|
{ PTP_OC_OpenSession, "OpenSession" },
|
|
|
|
{ PTP_OC_CloseSession, "CloseSession" },
|
|
|
|
{ PTP_OC_GetStorageIDs, "GetStorageIDs" },
|
|
|
|
{ PTP_OC_GetStorageInfo, "GetStorageInfo" },
|
|
|
|
{ PTP_OC_GetNumObjects, "GetNumObjects" },
|
|
|
|
{ PTP_OC_GetObjectHandles, "GetObjectHandles" },
|
|
|
|
{ PTP_OC_GetObjectInfo, "GetObjectInfo" },
|
|
|
|
{ PTP_OC_GetObject, "GetObject" },
|
|
|
|
{ PTP_OC_DeleteObject, "DeleteObject" },
|
|
|
|
{ PTP_OC_SendObjectInfo, "SendObjectInfo" },
|
|
|
|
{ PTP_OC_SendObject, "SendObject" },
|
|
|
|
{ PTP_OC_InitiateCapture, "InitiateCapture" },
|
|
|
|
{ PTP_OC_FormatStore, "FormatStore" },
|
|
|
|
{ PTP_OC_ResetDevice, "ResetDevice" },
|
|
|
|
{ PTP_OC_SelfTest, "SelfTest" },
|
|
|
|
{ PTP_OC_SetObjectProtection, "SetObjectProtection" },
|
|
|
|
{ PTP_OC_PowerDown, "PowerDown" },
|
|
|
|
{ PTP_OC_GetDevicePropDesc, "GetDevicePropDesc" },
|
|
|
|
{ PTP_OC_GetDevicePropValue, "GetDevicePropValue" },
|
|
|
|
{ PTP_OC_SetDevicePropValue, "SetDevicePropValue" },
|
|
|
|
{ PTP_OC_ResetDevicePropValue, "ResetDevicePropValue" },
|
|
|
|
{ PTP_OC_TerminateOpenCapture, "TerminateOpenCapture" },
|
|
|
|
{ PTP_OC_MoveObject, "MoveObject" },
|
|
|
|
{ PTP_OC_CopyObject, "CopyObject" },
|
|
|
|
{ PTP_OC_GetPartialObject, "GetPartialObject" },
|
|
|
|
{ PTP_OC_InitiateOpenCapture, "InitiateOpenCapture" },
|
|
|
|
{ PTP_OC_StartEnumHandles, "StartEnumHandles" },
|
|
|
|
{ PTP_OC_EnumHandles, "EnumHandles" },
|
|
|
|
{ PTP_OC_StopEnumHandles, "StopEnumHandles" },
|
|
|
|
{ PTP_OC_GetVendorExtensionMaps, "GetVendorExtensionMaps" },
|
|
|
|
{ PTP_OC_GetVendorDeviceInfo, "GetVendorDeviceInfo" },
|
|
|
|
{ PTP_OC_GetResizedImageObject, "GetResizedImageObject" },
|
|
|
|
{ PTP_OC_GetFilesystemManifest, "GetFilesystemManifest" },
|
|
|
|
{ PTP_OC_GetStreamInfo, "GetStreamInfo" },
|
|
|
|
{ PTP_OC_GetStream, "GetStream" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
static value_string_ext ptp_opcode_names_ext = VALUE_STRING_EXT_INIT(ptp_opcode_names);
|
|
|
|
|
|
|
|
static const value_string ptp_opcode_ek_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_OC_EK_GetSerial, "EK_GetSerial" },
|
|
|
|
{ PTP_OC_EK_SetSerial, "EK_SetSerial" },
|
|
|
|
{ PTP_OC_EK_SendFileObjectInfo, "EK_SendFileObjectInfo" },
|
|
|
|
{ PTP_OC_EK_SendFileObject, "EK_SendFileObject" },
|
|
|
|
{ PTP_OC_EK_SetText, "EK_SetText" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
static value_string_ext ptp_opcode_ek_names_ext = VALUE_STRING_EXT_INIT(ptp_opcode_ek_names);
|
|
|
|
|
|
|
|
static const value_string ptp_opcode_canon_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_OC_CANON_GetPartialObjectInfo, "CANON_GetPartialObjectInfo" },
|
|
|
|
{ PTP_OC_CANON_SetObjectArchive, "CANON_SetObjectArchive" },
|
|
|
|
{ PTP_OC_CANON_KeepDeviceOn, "CANON_KeepDeviceOn" },
|
|
|
|
{ PTP_OC_CANON_LockDeviceUI, "CANON_LockDeviceUI" },
|
|
|
|
{ PTP_OC_CANON_UnlockDeviceUI, "CANON_UnlockDeviceUI" },
|
|
|
|
{ PTP_OC_CANON_GetObjectHandleByName, "CANON_GetObjectHandleByName" },
|
|
|
|
{ PTP_OC_CANON_InitiateReleaseControl, "CANON_InitiateReleaseControl" },
|
|
|
|
{ PTP_OC_CANON_TerminateReleaseControl, "CANON_TerminateReleaseControl" },
|
|
|
|
{ PTP_OC_CANON_TerminatePlaybackMode, "CANON_TerminatePlaybackMode" },
|
|
|
|
{ PTP_OC_CANON_ViewfinderOn, "CANON_ViewfinderOn" },
|
|
|
|
{ PTP_OC_CANON_ViewfinderOff, "CANON_ViewfinderOff" },
|
|
|
|
{ PTP_OC_CANON_DoAeAfAwb, "CANON_DoAeAfAwb" },
|
|
|
|
{ PTP_OC_CANON_GetCustomizeSpec, "CANON_GetCustomizeSpec" },
|
|
|
|
{ PTP_OC_CANON_GetCustomizeItemInfo, "CANON_GetCustomizeItemInfo" },
|
|
|
|
{ PTP_OC_CANON_GetCustomizeData, "CANON_GetCustomizeData" },
|
|
|
|
{ PTP_OC_CANON_SetCustomizeData, "CANON_SetCustomizeData" },
|
|
|
|
{ PTP_OC_CANON_GetCaptureStatus, "CANON_GetCaptureStatus" },
|
|
|
|
{ PTP_OC_CANON_CheckEvent, "CANON_CheckEvent" },
|
|
|
|
{ PTP_OC_CANON_FocusLock, "CANON_FocusLock" },
|
|
|
|
{ PTP_OC_CANON_FocusUnlock, "CANON_FocusUnlock" },
|
|
|
|
{ PTP_OC_CANON_GetLocalReleaseParam, "CANON_GetLocalReleaseParam" },
|
|
|
|
{ PTP_OC_CANON_SetLocalReleaseParam, "CANON_SetLocalReleaseParam" },
|
|
|
|
{ PTP_OC_CANON_AskAboutPcEvf, "CANON_AskAboutPcEvf" },
|
|
|
|
{ PTP_OC_CANON_SendPartialObject, "CANON_SendPartialObject" },
|
|
|
|
{ PTP_OC_CANON_InitiateCaptureInMemory, "CANON_InitiateCaptureInMemory" },
|
|
|
|
{ PTP_OC_CANON_GetPartialObjectEx, "CANON_GetPartialObjectEx" },
|
|
|
|
{ PTP_OC_CANON_SetObjectTime, "CANON_SetObjectTime" },
|
|
|
|
{ PTP_OC_CANON_GetViewfinderImage, "CANON_GetViewfinderImage" },
|
|
|
|
{ PTP_OC_CANON_GetObjectAttributes, "CANON_GetObjectAttributes" },
|
|
|
|
{ PTP_OC_CANON_ChangeUSBProtocol, "CANON_ChangeUSBProtocol" },
|
|
|
|
{ PTP_OC_CANON_GetChanges, "CANON_GetChanges" },
|
|
|
|
{ PTP_OC_CANON_GetObjectInfoEx, "CANON_GetObjectInfoEx" },
|
|
|
|
{ PTP_OC_CANON_InitiateDirectTransfer, "CANON_InitiateDirectTransfer" },
|
|
|
|
{ PTP_OC_CANON_TerminateDirectTransfer, "CANON_TerminateDirectTransfer" },
|
|
|
|
{ PTP_OC_CANON_SendObjectInfoByPath, "CANON_SendObjectInfoByPath" },
|
|
|
|
{ PTP_OC_CANON_SendObjectByPath, "CANON_SendObjectByPath" },
|
|
|
|
{ PTP_OC_CANON_InitiateDirectTansferEx, "CANON_InitiateDirectTansferEx" },
|
|
|
|
{ PTP_OC_CANON_GetAncillaryObjectHandles, "CANON_GetAncillaryObjectHandles" },
|
|
|
|
{ PTP_OC_CANON_GetTreeInfo, "CANON_GetTreeInfo" },
|
|
|
|
{ PTP_OC_CANON_GetTreeSize, "CANON_GetTreeSize" },
|
|
|
|
{ PTP_OC_CANON_NotifyProgress, "CANON_NotifyProgress" },
|
|
|
|
{ PTP_OC_CANON_NotifyCancelAccepted, "CANON_NotifyCancelAccepted" },
|
|
|
|
{ PTP_OC_CANON_902C, "CANON_902C" },
|
|
|
|
{ PTP_OC_CANON_SetPairingInfo, "CANON_SetPairingInfo" },
|
|
|
|
{ PTP_OC_CANON_GetPairingInfo, "CANON_GetPairingInfo" },
|
|
|
|
{ PTP_OC_CANON_DeletePairingInfo, "CANON_DeletePairingInfo" },
|
|
|
|
{ PTP_OC_CANON_GetMACAddress, "CANON_GetMACAddress" },
|
|
|
|
{ PTP_OC_CANON_SetDisplayMonitor, "CANON_SetDisplayMonitor" },
|
|
|
|
{ PTP_OC_CANON_PairingComplete, "CANON_PairingComplete" },
|
|
|
|
{ PTP_OC_CANON_GetWirelessMAXChannel, "CANON_GetWirelessMAXChannel" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetStorageIDs, "CANON_EOS_GetStorageIDs" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetStorageInfo, "CANON_EOS_GetStorageInfo" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetObjectInfo, "CANON_EOS_GetObjectInfo" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetObject, "CANON_EOS_GetObject" },
|
|
|
|
{ PTP_OC_CANON_EOS_DeleteObject, "CANON_EOS_DeleteObject" },
|
|
|
|
{ PTP_OC_CANON_EOS_FormatStore, "CANON_EOS_FormatStore" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetPartialObject, "CANON_EOS_GetPartialObject" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetDeviceInfoEx, "CANON_EOS_GetDeviceInfoEx" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetObjectInfoEx, "CANON_EOS_GetObjectInfoEx" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetThumbEx, "CANON_EOS_GetThumbEx" },
|
|
|
|
{ PTP_OC_CANON_EOS_SendPartialObject, "CANON_EOS_SendPartialObject" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetObjectAttributes, "CANON_EOS_SetObjectAttributes" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetObjectTime, "CANON_EOS_GetObjectTime" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetObjectTime, "CANON_EOS_SetObjectTime" },
|
|
|
|
{ PTP_OC_CANON_EOS_RemoteRelease, "CANON_EOS_RemoteRelease" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetDevicePropValueEx, "CANON_EOS_SetDevicePropValueEx" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetRemoteMode, "CANON_EOS_GetRemoteMode" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetRemoteMode, "CANON_EOS_SetRemoteMode" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetEventMode, "CANON_EOS_SetEventMode" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetEvent, "CANON_EOS_GetEvent" },
|
|
|
|
{ PTP_OC_CANON_EOS_TransferComplete, "CANON_EOS_TransferComplete" },
|
|
|
|
{ PTP_OC_CANON_EOS_CancelTransfer, "CANON_EOS_CancelTransfer" },
|
|
|
|
{ PTP_OC_CANON_EOS_ResetTransfer, "CANON_EOS_ResetTransfer" },
|
|
|
|
{ PTP_OC_CANON_EOS_PCHDDCapacity, "CANON_EOS_PCHDDCapacity" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetUILock, "CANON_EOS_SetUILock" },
|
|
|
|
{ PTP_OC_CANON_EOS_ResetUILock, "CANON_EOS_ResetUILock" },
|
|
|
|
{ PTP_OC_CANON_EOS_KeepDeviceOn, "CANON_EOS_KeepDeviceOn" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetNullPacketMode, "CANON_EOS_SetNullPacketMode" },
|
|
|
|
{ PTP_OC_CANON_EOS_UpdateFirmware, "CANON_EOS_UpdateFirmware" },
|
|
|
|
{ PTP_OC_CANON_EOS_TransferCompleteDT, "CANON_EOS_TransferCompleteDT" },
|
|
|
|
{ PTP_OC_CANON_EOS_CancelTransferDT, "CANON_EOS_CancelTransferDT" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetWftProfile, "CANON_EOS_SetWftProfile" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetWftProfile, "CANON_EOS_GetWftProfile" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetProfileToWft, "CANON_EOS_SetProfileToWft" },
|
|
|
|
{ PTP_OC_CANON_EOS_BulbStart, "CANON_EOS_BulbStart" },
|
|
|
|
{ PTP_OC_CANON_EOS_BulbEnd, "CANON_EOS_BulbEnd" },
|
|
|
|
{ PTP_OC_CANON_EOS_RequestDevicePropValue, "CANON_EOS_RequestDevicePropValue" },
|
|
|
|
{ PTP_OC_CANON_EOS_RemoteReleaseOn, "CANON_EOS_RemoteReleaseOn" },
|
|
|
|
{ PTP_OC_CANON_EOS_RemoteReleaseOff, "CANON_EOS_RemoteReleaseOff" },
|
|
|
|
{ PTP_OC_CANON_EOS_InitiateViewfinder, "CANON_EOS_InitiateViewfinder" },
|
|
|
|
{ PTP_OC_CANON_EOS_TerminateViewfinder, "CANON_EOS_TerminateViewfinder" },
|
|
|
|
{ PTP_OC_CANON_EOS_GetViewFinderData, "CANON_EOS_GetViewFinderData" },
|
|
|
|
{ PTP_OC_CANON_EOS_DoAf, "CANON_EOS_DoAf" },
|
|
|
|
{ PTP_OC_CANON_EOS_DriveLens, "CANON_EOS_DriveLens" },
|
|
|
|
{ PTP_OC_CANON_EOS_DepthOfFieldPreview, "CANON_EOS_DepthOfFieldPreview" },
|
|
|
|
{ PTP_OC_CANON_EOS_ClickWB, "CANON_EOS_ClickWB" },
|
|
|
|
{ PTP_OC_CANON_EOS_Zoom, "CANON_EOS_Zoom" },
|
|
|
|
{ PTP_OC_CANON_EOS_ZoomPosition, "CANON_EOS_ZoomPosition" },
|
|
|
|
{ PTP_OC_CANON_EOS_SetLiveAfFrame, "CANON_EOS_SetLiveAfFrame" },
|
|
|
|
{ PTP_OC_CANON_EOS_AfCancel, "CANON_EOS_AfCancel" },
|
|
|
|
{ PTP_OC_CANON_EOS_FAPIMessageTX, "CANON_EOS_FAPIMessageTX" },
|
|
|
|
{ PTP_OC_CANON_EOS_FAPIMessageRX, "CANON_EOS_FAPIMessageRX" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
static value_string_ext ptp_opcode_canon_names_ext = VALUE_STRING_EXT_INIT(ptp_opcode_canon_names);
|
|
|
|
|
|
|
|
static const value_string ptp_opcode_nikon_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_OC_NIKON_GetProfileAllData, "NIKON_GetProfileAllData" },
|
|
|
|
{ PTP_OC_NIKON_SendProfileData, "NIKON_SendProfileData" },
|
|
|
|
{ PTP_OC_NIKON_SendProfileData, "NIKON_SendProfileData" },
|
|
|
|
{ PTP_OC_NIKON_DeleteProfile, "NIKON_DeleteProfile" },
|
|
|
|
{ PTP_OC_NIKON_SetProfileData, "NIKON_SetProfileData" },
|
|
|
|
{ PTP_OC_NIKON_AdvancedTransfer, "NIKON_AdvancedTransfer" },
|
|
|
|
{ PTP_OC_NIKON_GetFileInfoInBlock, "NIKON_GetFileInfoInBlock" },
|
|
|
|
{ PTP_OC_NIKON_Capture, "NIKON_Capture" },
|
|
|
|
{ PTP_OC_NIKON_AfDrive, "NIKON_AfDrive" },
|
|
|
|
{ PTP_OC_NIKON_SetControlMode, "NIKON_SetControlMode" },
|
|
|
|
{ PTP_OC_NIKON_DelImageSDRAM, "NIKON_DelImageSDRAM" },
|
|
|
|
{ PTP_OC_NIKON_GetLargeThumb, "NIKON_GetLargeThumb" },
|
|
|
|
{ PTP_OC_NIKON_CurveDownload, "NIKON_CurveDownload" },
|
|
|
|
{ PTP_OC_NIKON_CurveUpload, "NIKON_CurveUpload" },
|
|
|
|
{ PTP_OC_NIKON_CheckEvent, "NIKON_CheckEvent" },
|
|
|
|
{ PTP_OC_NIKON_DeviceReady, "NIKON_DeviceReady" },
|
|
|
|
{ PTP_OC_NIKON_SetPreWBData, "NIKON_SetPreWBData" },
|
|
|
|
{ PTP_OC_NIKON_GetVendorPropCodes, "NIKON_GetVendorPropCodes" },
|
|
|
|
{ PTP_OC_NIKON_AfCaptureSDRAM, "NIKON_AfCaptureSDRAM" },
|
|
|
|
{ PTP_OC_NIKON_GetPictCtrlData, "NIKON_GetPictCtrlData" },
|
|
|
|
{ PTP_OC_NIKON_SetPictCtrlData, "NIKON_SetPictCtrlData" },
|
|
|
|
{ PTP_OC_NIKON_DelCstPicCtrl, "NIKON_DelCstPicCtrl" },
|
|
|
|
{ PTP_OC_NIKON_GetPicCtrlCapability, "NIKON_GetPicCtrlCapability" },
|
|
|
|
{ PTP_OC_NIKON_GetPreviewImg, "NIKON_GetPreviewImg" },
|
|
|
|
{ PTP_OC_NIKON_StartLiveView, "NIKON_StartLiveView" },
|
|
|
|
{ PTP_OC_NIKON_EndLiveView, "NIKON_EndLiveView" },
|
|
|
|
{ PTP_OC_NIKON_GetLiveViewImg, "NIKON_GetLiveViewImg" },
|
|
|
|
{ PTP_OC_NIKON_MfDrive, "NIKON_MfDrive" },
|
|
|
|
{ PTP_OC_NIKON_ChangeAfArea, "NIKON_ChangeAfArea" },
|
|
|
|
{ PTP_OC_NIKON_AfDriveCancel, "NIKON_AfDriveCancel" },
|
|
|
|
{ PTP_OC_NIKON_GetDevicePTPIPInfo, "NIKON_GetDevicePTPIPInfo" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
static value_string_ext ptp_opcode_nikon_names_ext = VALUE_STRING_EXT_INIT(ptp_opcode_nikon_names);
|
|
|
|
|
|
|
|
static const value_string ptp_opcode_casio_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_OC_CASIO_STILL_START, "CASIO_STILL_START" },
|
|
|
|
{ PTP_OC_CASIO_STILL_STOP, "CASIO_STILL_STOP" },
|
|
|
|
{ PTP_OC_CASIO_FOCUS, "CASIO_FOCUS" },
|
|
|
|
{ PTP_OC_CASIO_CF_PRESS, "CASIO_CF_PRESS" },
|
|
|
|
{ PTP_OC_CASIO_CF_RELEASE, "CASIO_CF_RELEASE" },
|
|
|
|
{ PTP_OC_CASIO_GET_OBJECT_INFO, "CASIO_GET_OBJECT_INFO" },
|
|
|
|
{ PTP_OC_CASIO_SHUTTER, "CASIO_SHUTTER" },
|
|
|
|
{ PTP_OC_CASIO_GET_STILL_HANDLES, "CASIO_GET_STILL_HANDLES" },
|
|
|
|
{ PTP_OC_CASIO_STILL_RESET, "CASIO_STILL_RESET" },
|
|
|
|
{ PTP_OC_CASIO_HALF_PRESS, "CASIO_HALF_PRESS" },
|
|
|
|
{ PTP_OC_CASIO_HALF_RELEASE, "CASIO_HALF_RELEASE" },
|
|
|
|
{ PTP_OC_CASIO_CS_PRESS, "CASIO_CS_PRESS" },
|
|
|
|
{ PTP_OC_CASIO_CS_RELEASE, "CASIO_CS_RELEASE" },
|
|
|
|
{ PTP_OC_CASIO_ZOOM, "CASIO_ZOOM" },
|
|
|
|
{ PTP_OC_CASIO_CZ_PRESS, "CASIO_CZ_PRESS" },
|
|
|
|
{ PTP_OC_CASIO_CZ_RELEASE, "CASIO_CZ_RELEASE" },
|
|
|
|
{ PTP_OC_CASIO_MOVIE_START, "CASIO_MOVIE_START" },
|
|
|
|
{ PTP_OC_CASIO_MOVIE_STOP, "CASIO_MOVIE_STOP" },
|
|
|
|
{ PTP_OC_CASIO_MOVIE_PRESS, "CASIO_MOVIE_PRESS" },
|
|
|
|
{ PTP_OC_CASIO_MOVIE_RELEASE, "CASIO_MOVIE_RELEASE" },
|
|
|
|
{ PTP_OC_CASIO_GET_MOVIE_HANDLES, "CASIO_GET_MOVIE_HANDLES" },
|
|
|
|
{ PTP_OC_CASIO_MOVIE_RESET, "CASIO_MOVIE_RESET" },
|
|
|
|
{ PTP_OC_CASIO_GET_OBJECT, "CASIO_GET_OBJECT" },
|
|
|
|
{ PTP_OC_CASIO_GET_THUMBNAIL, "CASIO_GET_THUMBNAIL" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
static value_string_ext ptp_opcode_casio_names_ext = VALUE_STRING_EXT_INIT(ptp_opcode_casio_names);
|
|
|
|
|
|
|
|
static const value_string ptp_opcode_mtp_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_OC_MTP_GetObjectPropsSupported, "MTP_GetObjectPropsSupported" },
|
|
|
|
{ PTP_OC_MTP_GetObjectPropDesc, "MTP_GetObjectPropDesc" },
|
|
|
|
{ PTP_OC_MTP_GetObjectPropValue, "MTP_GetObjectPropValue" },
|
|
|
|
{ PTP_OC_MTP_SetObjectPropValue, "MTP_SetObjectPropValue" },
|
|
|
|
{ PTP_OC_MTP_GetObjPropList, "MTP_GetObjPropList" },
|
|
|
|
{ PTP_OC_MTP_SetObjPropList, "MTP_SetObjPropList" },
|
|
|
|
{ PTP_OC_MTP_GetInterdependendPropdesc, "MTP_GetInterdependendPropdesc" },
|
|
|
|
{ PTP_OC_MTP_SendObjectPropList, "MTP_SendObjectPropList" },
|
|
|
|
{ PTP_OC_MTP_GetObjectReferences, "MTP_GetObjectReferences" },
|
|
|
|
{ PTP_OC_MTP_SetObjectReferences, "MTP_SetObjectReferences" },
|
|
|
|
{ PTP_OC_MTP_UpdateDeviceFirmware, "MTP_UpdateDeviceFirmware" },
|
|
|
|
{ PTP_OC_MTP_Skip, "MTP_Skip" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_GetSecureTimeChallenge, "MTP_WMDRMPD_GetSecureTimeChallenge" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_GetSecureTimeResponse, "MTP_WMDRMPD_GetSecureTimeResponse" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_SetLicenseResponse, "MTP_WMDRMPD_SetLicenseResponse" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_GetSyncList, "MTP_WMDRMPD_GetSyncList" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_SendMeterChallengeQuery, "MTP_WMDRMPD_SendMeterChallengeQuery" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_GetMeterChallenge, "MTP_WMDRMPD_GetMeterChallenge" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_SetMeterResponse, "MTP_WMDRMPD_SetMeterResponse" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_CleanDataStore, "MTP_WMDRMPD_CleanDataStore" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_GetLicenseState, "MTP_WMDRMPD_GetLicenseState" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_SendWMDRMPDCommand, "MTP_WMDRMPD_SendWMDRMPDCommand" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_SendWMDRMPDRequest, "MTP_WMDRMPD_SendWMDRMPDRequest" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_SendWMDRMPDAppRequest, "MTP_WMDRMPD_SendWMDRMPDAppRequest" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_GetWMDRMPDAppResponse, "MTP_WMDRMPD_GetWMDRMPDAppResponse" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_EnableTrustedFilesOperations, "MTP_WMDRMPD_EnableTrustedFilesOperations" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_DisableTrustedFilesOperations, "MTP_WMDRMPD_DisableTrustedFilesOperations" },
|
|
|
|
{ PTP_OC_MTP_WMDRMPD_EndTrustedAppSession, "MTP_WMDRMPD_EndTrustedAppSession" },
|
|
|
|
{ PTP_OC_MTP_AAVT_OpenMediaSession, "MTP_AAVT_OpenMediaSession" },
|
|
|
|
{ PTP_OC_MTP_AAVT_CloseMediaSession, "MTP_AAVT_CloseMediaSession" },
|
|
|
|
{ PTP_OC_MTP_AAVT_GetNextDataBlock, "MTP_AAVT_GetNextDataBlock" },
|
|
|
|
{ PTP_OC_MTP_AAVT_SetCurrentTimePosition, "MTP_AAVT_SetCurrentTimePosition" },
|
|
|
|
{ PTP_OC_MTP_WMDRMND_SendRegistrationRequest, "MTP_WMDRMND_SendRegistrationRequest" },
|
|
|
|
{ PTP_OC_MTP_WMDRMND_GetRegistrationResponse, "MTP_WMDRMND_GetRegistrationResponse" },
|
|
|
|
{ PTP_OC_MTP_WMDRMND_GetProximityChallenge, "MTP_WMDRMND_GetProximityChallenge" },
|
|
|
|
{ PTP_OC_MTP_WMDRMND_SendProximityResponse, "MTP_WMDRMND_SendProximityResponse" },
|
|
|
|
{ PTP_OC_MTP_WMDRMND_SendWMDRMNDLicenseRequest, "MTP_WMDRMND_SendWMDRMNDLicenseRequest" },
|
|
|
|
{ PTP_OC_MTP_WMDRMND_GetWMDRMNDLicenseResponse, "MTP_WMDRMND_GetWMDRMNDLicenseResponse" },
|
|
|
|
{ PTP_OC_MTP_WMPPD_ReportAddedDeletedItems, "MTP_WMPPD_ReportAddedDeletedItems" },
|
|
|
|
{ PTP_OC_MTP_WMPPD_ReportAcquiredItems, "MTP_WMPPD_ReportAcquiredItems" },
|
|
|
|
{ PTP_OC_MTP_WMPPD_PlaylistObjectPref, "MTP_WMPPD_PlaylistObjectPref" },
|
|
|
|
{ PTP_OC_MTP_ZUNE_GETUNDEFINED001, "MTP_ZUNE_GETUNDEFINED001" },
|
|
|
|
{ PTP_OC_MTP_WPDWCN_ProcessWFCObject, "MTP_WPDWCN_ProcessWFCObject" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
static value_string_ext ptp_opcode_mtp_names_ext = VALUE_STRING_EXT_INIT(ptp_opcode_mtp_names);
|
|
|
|
|
|
|
|
static const value_string ptp_opcode_olympus_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_OC_OLYMPUS_Capture, "OLYMPUS_Capture" },
|
|
|
|
{ PTP_OC_OLYMPUS_SelfCleaning, "OLYMPUS_SelfCleaning" },
|
|
|
|
{ PTP_OC_OLYMPUS_SetRGBGain, "OLYMPUS_SetRGBGain" },
|
|
|
|
{ PTP_OC_OLYMPUS_SetPresetMode, "OLYMPUS_SetPresetMode" },
|
|
|
|
{ PTP_OC_OLYMPUS_SetWBBiasAll, "OLYMPUS_SetWBBiasAll" },
|
|
|
|
{ PTP_OC_OLYMPUS_GetCameraControlMode, "OLYMPUS_GetCameraControlMode" },
|
|
|
|
{ PTP_OC_OLYMPUS_SetCameraControlMode, "OLYMPUS_SetCameraControlMode" },
|
|
|
|
{ PTP_OC_OLYMPUS_SetWBRGBGain, "OLYMPUS_SetWBRGBGain" },
|
|
|
|
{ PTP_OC_OLYMPUS_GetDeviceInfo, "OLYMPUS_GetDeviceInfo" },
|
|
|
|
{ PTP_OC_OLYMPUS_Init1, "OLYMPUS_Init1" },
|
|
|
|
{ PTP_OC_OLYMPUS_SetDateTime, "OLYMPUS_SetDateTime" },
|
|
|
|
{ PTP_OC_OLYMPUS_GetDateTime, "OLYMPUS_GetDateTim" },
|
|
|
|
{ PTP_OC_OLYMPUS_SetCameraID, "OLYMPUS_SetCameraID" },
|
|
|
|
{ PTP_OC_OLYMPUS_GetCameraID, "OLYMPUS_GetCameraID" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
2015-05-23 02:43:53 +00:00
|
|
|
static value_string_ext ptp_opcode_olympus_names_ext = VALUE_STRING_EXT_INIT(ptp_opcode_olympus_names);
|
2013-11-25 16:57:43 +00:00
|
|
|
|
|
|
|
static const value_string ptp_respcode_names[] = {
|
|
|
|
{ PTP_RC_OK, "OK" },
|
|
|
|
{ PTP_RC_GeneralError, "GeneralError" },
|
|
|
|
{ PTP_RC_SessionNotOpen, "SessionNotOpen" },
|
|
|
|
{ PTP_RC_InvalidTransactionID, "InvalidTransactionID" },
|
|
|
|
{ PTP_RC_OperationNotSupported, "OperationNotSupported" },
|
|
|
|
{ PTP_RC_ParameterNotSupported, "ParameterNotSupported" },
|
|
|
|
{ PTP_RC_IncompleteTransfer, "IncompleteTransfer" },
|
|
|
|
{ PTP_RC_InvalidStorageId, "InvalidStorageId" },
|
|
|
|
{ PTP_RC_InvalidObjectHandle, "InvalidObjectHandle" },
|
|
|
|
{ PTP_RC_DevicePropNotSupported, "DevicePropNotSupported" },
|
|
|
|
{ PTP_RC_InvalidObjectFormatCode, "InvalidObjectFormatCode" },
|
|
|
|
{ PTP_RC_StoreFull, "StoreFull" },
|
|
|
|
{ PTP_RC_StoreReadOnly, "StoreReadOnly" },
|
|
|
|
{ PTP_RC_AccessDenied, "AccessDenied" },
|
|
|
|
{ PTP_RC_NoThumbnailPresent, "NoThumbnailPresent" },
|
|
|
|
{ PTP_RC_SelfTestFailed, "SelfTestFailed" },
|
|
|
|
{ PTP_RC_PartialDeletion, "PartialDeletion" },
|
|
|
|
{ PTP_RC_StoreNotAvailable, "StoreNotAvailable" },
|
|
|
|
{ PTP_RC_SpecificationByFormatUnsupported, "SpecificationByFormatUnsupported" },
|
|
|
|
{ PTP_RC_NoValidObjectInfo, "NoValidObjectInfo" },
|
|
|
|
{ PTP_RC_InvalidCodeFormat, "InvalidCodeFormat" },
|
|
|
|
{ PTP_RC_UnknownVendorCode, "UnknownVendorCode" },
|
|
|
|
{ PTP_RC_CaptureAlreadyTerminated, "CaptureAlreadyTerminated" },
|
|
|
|
{ PTP_RC_DeviceBusy, "DeviceBusy" },
|
|
|
|
{ PTP_RC_InvalidParentObject, "InvalidParentObject" },
|
|
|
|
{ PTP_RC_InvalidDevicePropFormat, "InvalidDevicePropFormat" },
|
|
|
|
{ PTP_RC_InvalidDevicePropValue, "InvalidDevicePropValue" },
|
|
|
|
{ PTP_RC_InvalidParameter, "InvalidParameter" },
|
|
|
|
{ PTP_RC_SessionAlreadyOpened, "SessionAlreadyOpened" },
|
|
|
|
{ PTP_RC_TransactionCanceled, "TransactionCanceled" },
|
|
|
|
{ PTP_RC_SpecificationOfDestinationUnsupported, "SpecificationOfDestinationUnsupported" },
|
|
|
|
{ PTP_RC_InvalidEnumHandle, "InvalidEnumHandle" },
|
|
|
|
{ PTP_RC_NoStreamEnabled, "NoStreamEnabled" },
|
|
|
|
{ PTP_RC_InvalidDataSet, "InvalidDataSet" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
/* static value_string_ext ptp_respcode_names_ext = VALUE_STRING_EXT_INIT(ptp_respcode_names); */
|
|
|
|
|
|
|
|
static const value_string ptp_respcode_ek_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_RC_EK_FilenameRequired, "EK_FilenameRequired" },
|
|
|
|
{ PTP_RC_EK_FilenameConflicts, "EK_FilenameConflicts" },
|
|
|
|
{ PTP_RC_EK_FilenameInvalid, "EK_FilenameInvalid" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string ptp_respcode_nikon_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_RC_NIKON_HardwareError, "NIKON_HardwareError" },
|
|
|
|
{ PTP_RC_NIKON_OutOfFocus, "NIKON_OutOfFocus" },
|
|
|
|
{ PTP_RC_NIKON_ChangeCameraModeFailed, "NIKON_ChangeCameraModeFailed" },
|
|
|
|
{ PTP_RC_NIKON_InvalidStatus, "NIKON_InvalidStatus" },
|
|
|
|
{ PTP_RC_NIKON_SetPropertyNotSupported, "NIKON_SetPropertyNotSupported" },
|
|
|
|
{ PTP_RC_NIKON_WbResetError, "NIKON_WbResetError" },
|
|
|
|
{ PTP_RC_NIKON_DustReferenceError, "NIKON_DustReferenceError" },
|
|
|
|
{ PTP_RC_NIKON_ShutterSpeedBulb, "NIKON_ShutterSpeedBulb" },
|
|
|
|
{ PTP_RC_NIKON_MirrorUpSequence, "NIKON_MirrorUpSequence" },
|
|
|
|
{ PTP_RC_NIKON_CameraModeNotAdjustFNumber, "NIKON_CameraModeNotAdjustFNumber" },
|
|
|
|
{ PTP_RC_NIKON_NotLiveView, "NIKON_NotLiveView" },
|
|
|
|
{ PTP_RC_NIKON_MfDriveStepEnd, "NIKON_MfDriveStepEnd" },
|
|
|
|
{ PTP_RC_NIKON_MfDriveStepInsufficiency, "NIKON_MfDriveStepInsufficiency" },
|
|
|
|
{ PTP_RC_NIKON_AdvancedTransferCancel, "NIKON_AdvancedTransferCancel" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string ptp_respcode_canon_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_RC_CANON_UNKNOWN_COMMAND, "CANON_UNKNOWN_COMMAND" },
|
|
|
|
{ PTP_RC_CANON_OPERATION_REFUSED, "CANON_OPERATION_REFUSED" },
|
|
|
|
{ PTP_RC_CANON_LENS_COVER, "CANON_LENS_COVER" },
|
|
|
|
{ PTP_RC_CANON_BATTERY_LOW, "CANON_BATTERY_LOW" },
|
|
|
|
{ PTP_RC_CANON_NOT_READY, "CANON_NOT_READY" },
|
|
|
|
{ PTP_RC_CANON_A009, "CANON_A009" },
|
2015-05-23 02:43:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string ptp_respcode_mtp_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTP_RC_MTP_Undefined, "MTP_Undefined" },
|
|
|
|
{ PTP_RC_MTP_Invalid_ObjectPropCode, "MTP_Invalid_ObjectPropCode" },
|
|
|
|
{ PTP_RC_MTP_Invalid_ObjectProp_Format, "MTP_Invalid_ObjectProp_Format" },
|
|
|
|
{ PTP_RC_MTP_Invalid_ObjectProp_Value, "MTP_Invalid_ObjectProp_Value" },
|
|
|
|
{ PTP_RC_MTP_Invalid_ObjectReference, "MTP_Invalid_ObjectReference" },
|
|
|
|
{ PTP_RC_MTP_Invalid_Dataset, "MTP_Invalid_Dataset" },
|
|
|
|
{ PTP_RC_MTP_Specification_By_Group_Unsupported, "MTP_Specification_By_Group_Unsupported" },
|
|
|
|
{ PTP_RC_MTP_Specification_By_Depth_Unsupported, "MTP_Specification_By_Depth_Unsupported" },
|
|
|
|
{ PTP_RC_MTP_Object_Too_Large, "MTP_Object_Too_Large" },
|
|
|
|
{ PTP_RC_MTP_ObjectProp_Not_Supported, "MTP_ObjectProp_Not_Supported" },
|
|
|
|
{ PTP_RC_MTP_Invalid_Media_Session_ID, "MTP_Invalid_Media_Session_ID" },
|
|
|
|
{ PTP_RC_MTP_Media_Session_Limit_Reached, "MTP_Media_Session_Limit_Reached" },
|
|
|
|
{ PTP_RC_MTP_No_More_Data, "MTP_No_More_Data" },
|
|
|
|
{ PTP_RC_MTP_Invalid_WFC_Syntax, "MTP_Invalid_WFC_Syntax" },
|
|
|
|
{ PTP_RC_MTP_WFC_Version_Not_Supported, "MTP_WFC_Version_Not_Supported" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* String Names of packet types [3] & [4] */
|
|
|
|
/* PTP/IP definitions */
|
|
|
|
/* enums reformatted from [4] */
|
2013-05-10 01:37:14 +00:00
|
|
|
typedef enum {
|
|
|
|
PTPIP_INVALID = 0,
|
|
|
|
PTPIP_INIT_COMMAND_REQUEST = 1,
|
|
|
|
PTPIP_INIT_COMMAND_ACK = 2,
|
|
|
|
PTPIP_INIT_EVENT_REQUEST = 3,
|
|
|
|
PTPIP_INIT_EVENT_ACK = 4,
|
|
|
|
PTPIP_INIT_FAIL = 5,
|
2013-11-25 16:57:43 +00:00
|
|
|
PTPIP_CMD_REQUEST = 6, /* possibly Operation request in [1] 2.3.6 agrees with [3] */
|
|
|
|
PTPIP_CMD_RESPONSE = 7, /* possibly Operation response in [1] 2.3.7 agrees with [3] */
|
2013-05-10 01:37:14 +00:00
|
|
|
PTPIP_EVENT = 8,
|
|
|
|
PTPIP_START_DATA_PACKET = 9,
|
|
|
|
PTPIP_DATA_PACKET = 10,
|
|
|
|
PTPIP_CANCEL_TRANSACTION = 11,
|
|
|
|
PTPIP_END_DATA_PACKET = 12,
|
2013-11-25 16:57:43 +00:00
|
|
|
PTPIP_PING = 13, /* possibly Probe Request in [1] 2.3.13 */
|
|
|
|
PTPIP_PONG = 14 /* possibly Probe Response in [1] 2.3.14 */
|
2013-05-10 01:37:14 +00:00
|
|
|
} ptpip_pktType;
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* Unless otherwise stated, names are based on info in [3] */
|
2013-05-10 01:37:14 +00:00
|
|
|
static const value_string ptpip_pktType_names[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTPIP_INVALID, "Invalid" },
|
2013-05-10 01:37:14 +00:00
|
|
|
{ PTPIP_INIT_COMMAND_REQUEST, "Init Command Request Packet" },
|
|
|
|
{ PTPIP_INIT_COMMAND_ACK, "Init Command ACK Packet" },
|
|
|
|
{ PTPIP_INIT_EVENT_REQUEST, "Init Event Request Packet" },
|
|
|
|
{ PTPIP_INIT_EVENT_ACK, "Init Event Ack Packet"},
|
|
|
|
{ PTPIP_INIT_FAIL, "Init Fail Packet"},
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTPIP_CMD_REQUEST, "Operation Request Packet"}, /* string based on [1] */
|
|
|
|
{ PTPIP_CMD_RESPONSE, "Operation Response Packet"}, /* string based on [1] */
|
2013-05-10 01:37:14 +00:00
|
|
|
{ PTPIP_EVENT, "Event Packet"},
|
|
|
|
{ PTPIP_START_DATA_PACKET, "Start Data Packet"},
|
|
|
|
{ PTPIP_DATA_PACKET, "Data Packet"},
|
|
|
|
{ PTPIP_CANCEL_TRANSACTION, "Cancel Packet"},
|
|
|
|
{ PTPIP_END_DATA_PACKET, "End Data Packet"},
|
2013-11-25 16:57:43 +00:00
|
|
|
{ PTPIP_PING, "Probe Request Packet"}, /* string based on [1] */
|
|
|
|
{ PTPIP_PONG, "Probe Response Packet"}, /* string based on [1] */
|
2013-05-10 01:37:14 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
2013-11-25 16:57:43 +00:00
|
|
|
static value_string_ext ptpip_pktType_names_ext = VALUE_STRING_EXT_INIT(ptpip_pktType_names);
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Primary method to dissect a PTP/IP packet. When a subtype is encounter,
|
|
|
|
* the method will call a subdissector.
|
|
|
|
*/
|
|
|
|
static
|
|
|
|
int dissect_ptpIP (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
|
|
|
{
|
|
|
|
proto_item *item_ptr;
|
|
|
|
proto_tree *ptp_tree;
|
2013-11-25 16:57:43 +00:00
|
|
|
guint16 offset = 0;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
guint32 pktType;
|
|
|
|
|
|
|
|
/* Check that there's enough data */
|
2015-06-23 22:17:27 +00:00
|
|
|
if ( tvb_captured_length_remaining(tvb, offset) < 8 ) /* ptp-photo smallest packet size is 8 */
|
2013-05-10 01:37:14 +00:00
|
|
|
return (0);
|
|
|
|
|
|
|
|
col_set_str(pinfo->cinfo,COL_PROTOCOL, "PTP/IP");
|
|
|
|
|
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Picture Transfer Protocol");
|
|
|
|
|
|
|
|
item_ptr = proto_tree_add_protocol_format(tree, proto_ptpIP, tvb, offset,
|
|
|
|
-1, "Picture Transfer Protocol");
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* creating the tree */
|
2013-05-10 01:37:14 +00:00
|
|
|
ptp_tree = proto_item_add_subtree(item_ptr, ett_ptpIP);
|
2013-11-25 16:57:43 +00:00
|
|
|
/* [1] Defines first 2 fields as length and packet type. (Section 2.3)
|
2013-05-10 01:37:14 +00:00
|
|
|
* Also note: the standard lists all multibyte values in PTP-IP as little-endian
|
|
|
|
*/
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* note: len field size included in total len */
|
2013-05-10 01:37:14 +00:00
|
|
|
proto_tree_add_item(ptp_tree, hf_ptpIP_len, tvb, offset, 4, ENC_LITTLE_ENDIAN);
|
2013-11-25 16:57:43 +00:00
|
|
|
offset += 4;
|
|
|
|
/* @todo:maybe add some length verification checks to see if len advertised matches actual len */
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
pktType = tvb_get_letohl(tvb, offset);
|
|
|
|
proto_tree_add_item(ptp_tree, hf_ptpIP_pktType, tvb, offset, 4, ENC_LITTLE_ENDIAN);
|
2013-11-25 16:57:43 +00:00
|
|
|
offset += 4;
|
2013-05-10 01:37:14 +00:00
|
|
|
switch (pktType) {
|
|
|
|
case PTPIP_INIT_COMMAND_REQUEST:
|
|
|
|
dissect_ptpIP_init_command_request(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_INIT_COMMAND_ACK:
|
|
|
|
dissect_ptpIP_init_command_ack(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_INIT_EVENT_REQUEST:
|
|
|
|
dissect_ptpIP_init_event_request(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_INIT_EVENT_ACK:
|
|
|
|
dissect_ptpIP_init_event_ack(pinfo);
|
|
|
|
break;
|
|
|
|
case PTPIP_CMD_REQUEST:
|
|
|
|
dissect_ptpIP_operation_request(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_CMD_RESPONSE:
|
|
|
|
dissect_ptpIP_operation_response(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_EVENT:
|
|
|
|
dissect_ptpIP_event(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_START_DATA_PACKET:
|
|
|
|
dissect_ptpIP_start_data(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_DATA_PACKET:
|
|
|
|
dissect_ptpIP_data(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
case PTPIP_END_DATA_PACKET:
|
|
|
|
dissect_ptpIP_end_data(tvb, pinfo, ptp_tree, &offset);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Method to dissect the Init Command Request sent by the Initiator
|
|
|
|
* in the connection. This packet is defined by [1] Section 2.3.1
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_init_command_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 0;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Init Command Request");
|
|
|
|
|
|
|
|
dissect_ptpIP_guid(tvb, pinfo, tree, offset);
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* grabbing the name */
|
2013-05-10 01:37:14 +00:00
|
|
|
dissect_ptpIP_unicode_name(tvb, pinfo, tree, offset);
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* grabbing protocol version
|
2014-09-09 18:05:52 +00:00
|
|
|
* Note: [3] does not list this in the packet field. . [1] 2.3.1 states it's the last 4
|
2013-05-10 01:37:14 +00:00
|
|
|
* bytes of the packet.
|
|
|
|
*/
|
|
|
|
dissect_ptpIP_protocol_version(tvb, tree, offset);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Method to dissect the Init Command Ack sent by the Responder
|
|
|
|
* in the connection. This packet is defined by [1] Section 2.3.2
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_init_command_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
guint32 connectionNumber;
|
|
|
|
|
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Init Command Ack");
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* Grabbing the Connection Number */
|
2013-05-10 01:37:14 +00:00
|
|
|
connectionNumber = tvb_get_letohl(tvb, *offset);
|
|
|
|
proto_tree_add_item(tree, hf_ptpIP_connectionNumber, tvb, *offset, 4,ENC_LITTLE_ENDIAN);
|
|
|
|
col_append_fstr(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
" Connection #:%u",
|
|
|
|
connectionNumber);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 4;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
dissect_ptpIP_guid(tvb, pinfo, tree, offset);
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* grabbing name */
|
2013-05-10 01:37:14 +00:00
|
|
|
dissect_ptpIP_unicode_name(tvb,pinfo, tree, offset);
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* grabbing protocol version. Note: like in the Init Command Request, [3] doesn't mention
|
2013-05-10 01:37:14 +00:00
|
|
|
* this field, but [1] Section 2.3.2 does.
|
|
|
|
*/
|
2013-11-25 16:57:43 +00:00
|
|
|
|
|
|
|
|
2013-05-10 01:37:14 +00:00
|
|
|
dissect_ptpIP_protocol_version(tvb, tree, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the Init Event Request packet specified in [1] Section 2.3.3.
|
|
|
|
* Standard states that the packet only has 1 field.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_init_event_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
guint32 connectionNumber;
|
|
|
|
|
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Init Event Request");
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* Grabbing the Connection Number */
|
2013-05-10 01:37:14 +00:00
|
|
|
connectionNumber = tvb_get_letohl(tvb, *offset);
|
|
|
|
proto_tree_add_item(tree, hf_ptpIP_connectionNumber, tvb, *offset, 4,ENC_LITTLE_ENDIAN);
|
|
|
|
col_append_fstr(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
" Connection #:%u",
|
|
|
|
connectionNumber);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 4;
|
2013-05-10 01:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the Init Event Ack packet specified in [1] Section 2.3.4
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_init_event_ack(packet_info *pinfo)
|
|
|
|
{
|
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Init Event Ack");
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* packet has no payload. */
|
2013-05-10 01:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the Operation Request Packet specified in [1] Section 2.3.6
|
|
|
|
* Note: many of the fields in this packet move from PTP/IP to PTP layer
|
|
|
|
* of the stack. Work will need to be done in future iterations to make this
|
|
|
|
* compatible with PTP/USB.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_operation_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
2013-11-25 16:57:43 +00:00
|
|
|
guint16 opcode;
|
|
|
|
guint16 transactionID_offset = *offset; /* need to save this to output transaction id in pinfo */
|
2013-05-10 01:37:14 +00:00
|
|
|
|
2013-10-29 14:09:20 +00:00
|
|
|
col_set_str(
|
2013-05-10 01:37:14 +00:00
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Operation Request Packet ");
|
|
|
|
|
|
|
|
proto_tree_add_item(tree,hf_ptpIP_dataPhaseInfo, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 4;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
opcode = tvb_get_letohs(tvb, *offset);
|
2015-05-23 02:43:53 +00:00
|
|
|
if (opcode & PTP_OC_EXTENSION_MASK)
|
|
|
|
{
|
|
|
|
if (pref_vendor == PTP_VENDOR_UNKNOWN)
|
|
|
|
{
|
|
|
|
proto_tree_add_item(tree, hf_ptp_vendor_opCode, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
value_string_ext* vendor_values = NULL;
|
|
|
|
|
|
|
|
switch(pref_vendor)
|
|
|
|
{
|
|
|
|
case PTP_VENDOR_EASTMAN_KODAK:
|
|
|
|
vendor_values = &ptp_opcode_ek_names_ext;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_CANON:
|
|
|
|
vendor_values = &ptp_opcode_canon_names_ext;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_NIKON:
|
|
|
|
vendor_values = &ptp_opcode_nikon_names_ext;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_CASIO:
|
|
|
|
vendor_values = &ptp_opcode_casio_names_ext;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_MTP:
|
|
|
|
vendor_values = &ptp_opcode_mtp_names_ext;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_OLYMPUS:
|
|
|
|
vendor_values = &ptp_opcode_olympus_names_ext;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DISSECTOR_ASSERT(FALSE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
proto_tree_add_uint_format_value(tree, hf_ptp_vendor_opCode, tvb, *offset, 2, opcode, "%s (0x%04x)",
|
|
|
|
val_to_str_ext_const(opcode, vendor_values, "Unknown"), opcode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
proto_tree_add_item(tree, hf_ptp_opCode, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
|
|
|
|
}
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 2;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
transactionID_offset = *offset; /* we'll dissect the transactionID later because
|
|
|
|
opcode handling erases the column */
|
|
|
|
*offset += 4;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* carving out the parameters. [1] 2.3.6 states there can be at most 5. Params are defined in [2] 10.1 & 10.4 */
|
2013-05-10 01:37:14 +00:00
|
|
|
switch (opcode)
|
|
|
|
{
|
|
|
|
case PTP_OC_GetDeviceInfo:
|
2013-11-25 16:57:43 +00:00
|
|
|
/* [1] 10.5.1 */
|
2013-05-10 01:37:14 +00:00
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"GetDeviceInfo");
|
2013-11-25 16:57:43 +00:00
|
|
|
/* No parameters */
|
2013-05-10 01:37:14 +00:00
|
|
|
break;
|
|
|
|
case PTP_OC_OpenSession:
|
|
|
|
dissect_ptp_opCode_openSession(tvb, pinfo, tree, offset);
|
|
|
|
break;
|
|
|
|
case PTP_OC_CloseSession:
|
2013-11-25 16:57:43 +00:00
|
|
|
/* [1] 10.5.3 */
|
2013-05-10 01:37:14 +00:00
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"CloseSession");
|
2013-11-25 16:57:43 +00:00
|
|
|
/* No parameters */
|
2013-05-10 01:37:14 +00:00
|
|
|
break;
|
|
|
|
case PTP_OC_GetStorageIDs:
|
2013-11-25 16:57:43 +00:00
|
|
|
/* [2] 10.5.4 */
|
2013-05-10 01:37:14 +00:00
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"GetStorageIDs");
|
2013-11-25 16:57:43 +00:00
|
|
|
/* states data is a storage array. Needs eventual investigation. */
|
2013-05-10 01:37:14 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
dissect_ptp_transactionID(tvb, pinfo, tree, &transactionID_offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the Operation Response Packet specified in [1] Section 2.3.7
|
|
|
|
* Note: many of the fields in this packet move from PTP/IP to PTP layer
|
|
|
|
* of the stack. Work will need to be done in future iterations to make this
|
|
|
|
* compatible with PTP/USB.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_operation_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
2015-05-23 02:43:53 +00:00
|
|
|
guint16 resp;
|
|
|
|
|
2013-10-29 14:09:20 +00:00
|
|
|
col_set_str(
|
2013-05-10 01:37:14 +00:00
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Operation Response Packet ");
|
|
|
|
|
2015-05-23 02:43:53 +00:00
|
|
|
resp = tvb_get_letohs(tvb, *offset);
|
|
|
|
if (resp & PTP_OC_EXTENSION_MASK)
|
|
|
|
{
|
|
|
|
const value_string* vendor_values = NULL;
|
|
|
|
switch(pref_vendor)
|
|
|
|
{
|
|
|
|
case PTP_VENDOR_EASTMAN_KODAK:
|
|
|
|
vendor_values = ptp_respcode_ek_names;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_CANON:
|
|
|
|
vendor_values = ptp_respcode_canon_names;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_NIKON:
|
|
|
|
vendor_values = ptp_respcode_nikon_names;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_MTP:
|
|
|
|
vendor_values = ptp_respcode_mtp_names;
|
|
|
|
break;
|
|
|
|
case PTP_VENDOR_UNKNOWN:
|
|
|
|
case PTP_VENDOR_CASIO:
|
|
|
|
case PTP_VENDOR_OLYMPUS:
|
|
|
|
default:
|
|
|
|
vendor_values = ptp_respcode_names;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
proto_tree_add_uint_format_value(tree, hf_ptp_vendor_opCode, tvb, *offset, 2, resp, "%s (0x%04x)",
|
|
|
|
val_to_str_const(resp, vendor_values, "Unknown"), resp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
proto_tree_add_item(tree, hf_ptp_respCode, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
|
|
|
|
}
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 2;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
dissect_ptp_transactionID(tvb, pinfo, tree, offset);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the Event Packet specified in [1] Section 2.3.8
|
|
|
|
* Note: many of the fields in this packet move from PTP/IP to PTP layer
|
|
|
|
* of the stack. Work will need to be done in future iterations to make this
|
|
|
|
* compatible with PTP/USB.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
2013-10-29 14:09:20 +00:00
|
|
|
col_set_str(
|
2013-05-10 01:37:14 +00:00
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Event Packet ");
|
|
|
|
|
|
|
|
proto_tree_add_item(tree, hf_ptp_eventCode, tvb, *offset, 2, ENC_LITTLE_ENDIAN);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 2;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
dissect_ptp_transactionID(tvb, pinfo, tree, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the Event Packet specified in [1] Section 2.3.9
|
|
|
|
* Note: many of the fields in this packet move from PTP/IP to PTP layer
|
|
|
|
* of the stack. Work will need to be done in future iterations to make this
|
|
|
|
* compatible with PTP/USB.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_start_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
2013-11-25 16:57:43 +00:00
|
|
|
guint64 dataLen;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
2013-10-29 14:09:20 +00:00
|
|
|
col_set_str(
|
2013-05-10 01:37:14 +00:00
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Start Data Packet ");
|
|
|
|
|
|
|
|
dissect_ptp_transactionID(tvb, pinfo, tree, offset);
|
|
|
|
|
|
|
|
|
|
|
|
dataLen = tvb_get_letoh64(tvb, *offset);
|
|
|
|
proto_tree_add_item(tree, hf_ptp_totalDataLength, tvb, *offset, 8, ENC_LITTLE_ENDIAN);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 8;
|
|
|
|
if (dataLen == G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) /* [1] specifies in 2.3.9 if total data len
|
|
|
|
is this value then len is unknown */
|
2013-05-10 01:37:14 +00:00
|
|
|
{
|
|
|
|
col_append_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
" Data Length Unknown");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void dissect_ptpIP_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
|
2013-10-29 14:09:20 +00:00
|
|
|
col_set_str(
|
2013-05-10 01:37:14 +00:00
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"Data Packet ");
|
|
|
|
|
|
|
|
dissect_ptp_transactionID(tvb, pinfo, tree, offset);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the End Data specified in [1] Section 2.3.11
|
|
|
|
* Note: many of the fields in this packet move from PTP/IP to PTP layer
|
|
|
|
* of the stack. Work will need to be done in future iterations to make this
|
|
|
|
* compatible with PTP/USB.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_end_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
|
2013-10-29 14:09:20 +00:00
|
|
|
col_set_str(
|
2013-05-10 01:37:14 +00:00
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"End Data Packet ");
|
|
|
|
|
|
|
|
dissect_ptp_transactionID(tvb, pinfo, tree, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dissects the Opcode Open Session as defined by [2] 10.5.2
|
|
|
|
*/
|
|
|
|
void dissect_ptp_opCode_openSession(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
col_set_str(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
"OpenSession");
|
|
|
|
|
|
|
|
proto_tree_add_item(tree, hf_ptp_opCode_param_sessionID, tvb, *offset, 4 , ENC_LITTLE_ENDIAN);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 4;
|
2013-05-10 01:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The transaction ID is defined in [2] 9.3.1
|
|
|
|
* and used in multiple message types. This method handles
|
|
|
|
* parsing the field and adding the value to the info
|
|
|
|
* column.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void dissect_ptp_transactionID(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
guint32 transactionID;
|
|
|
|
|
|
|
|
transactionID = tvb_get_letohl(tvb, *offset);
|
|
|
|
proto_tree_add_item(tree, hf_ptp_transactionID, tvb, *offset, 4, ENC_LITTLE_ENDIAN);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += 4;
|
2013-05-10 01:37:14 +00:00
|
|
|
col_append_fstr(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
" Transaction ID: %d",
|
|
|
|
transactionID);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This method handles dissecting the Unicode name that is
|
|
|
|
* specificed in multiple packets.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_unicode_name(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
2016-06-26 14:52:37 +00:00
|
|
|
const guint8 *name;
|
|
|
|
gint nameLen;
|
2013-05-10 01:37:14 +00:00
|
|
|
|
|
|
|
nameLen = tvb_unicode_strsize(tvb, *offset);
|
2016-06-26 14:52:37 +00:00
|
|
|
proto_tree_add_item_ret_string(tree, hf_ptpIP_name, tvb, *offset, nameLen, ENC_UTF_16|ENC_LITTLE_ENDIAN, wmem_packet_scope(), &name);
|
2013-11-25 16:57:43 +00:00
|
|
|
*offset += nameLen;
|
2016-06-26 14:52:37 +00:00
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, " Name: %s", name);
|
2013-05-10 01:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Method dissects the protocol version from the packets.
|
|
|
|
* Additional note, section 3 of [1] defines the Binary Protocol version
|
|
|
|
* as 0x00010000 == 1.0 where the Most significant bits are the major version and the least
|
|
|
|
* significant bits are the minor version.
|
|
|
|
*/
|
|
|
|
void dissect_ptpIP_protocol_version(tvbuff_t *tvb, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
guint8 version[30];
|
2013-05-10 01:37:14 +00:00
|
|
|
guint32 protoVersion;
|
|
|
|
guint16 majorVersion, minorVersion;
|
|
|
|
|
|
|
|
protoVersion = tvb_get_letohl(tvb, *offset);
|
2013-11-25 16:57:43 +00:00
|
|
|
/* logic to format version */
|
2013-05-10 01:37:14 +00:00
|
|
|
minorVersion = protoVersion & 0xFFFF;
|
|
|
|
majorVersion = (protoVersion & 0xFFFF0000) >>16;
|
2013-11-25 16:57:43 +00:00
|
|
|
g_snprintf(version, sizeof(version), "%u.%u", majorVersion, minorVersion);
|
2013-05-10 01:37:14 +00:00
|
|
|
proto_tree_add_string(tree, hf_ptpIP_version, tvb, *offset, 4, version);
|
|
|
|
*offset += 4;
|
|
|
|
}
|
|
|
|
|
2013-11-25 16:57:43 +00:00
|
|
|
/* Grabbing the GUID */
|
2013-05-10 01:37:14 +00:00
|
|
|
void dissect_ptpIP_guid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 *offset)
|
|
|
|
{
|
|
|
|
guint8 *guid;
|
|
|
|
|
2015-01-07 15:11:22 +00:00
|
|
|
guid = tvb_bytes_to_str(wmem_packet_scope(), tvb, *offset, PTPIP_GUID_SIZE);
|
2013-05-10 01:37:14 +00:00
|
|
|
proto_tree_add_item(tree, hf_ptpIP_guid, tvb, *offset, PTPIP_GUID_SIZE, ENC_NA);
|
|
|
|
*offset += PTPIP_GUID_SIZE;
|
|
|
|
col_append_fstr(
|
|
|
|
pinfo->cinfo,
|
|
|
|
COL_INFO,
|
|
|
|
" GUID: %s",
|
|
|
|
guid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void proto_register_ptpip( void )
|
|
|
|
{
|
|
|
|
static hf_register_info hf[] = {
|
2013-11-25 16:57:43 +00:00
|
|
|
/* PTP/IP layer */
|
2013-05-10 01:37:14 +00:00
|
|
|
{ &hf_ptpIP_len, {
|
|
|
|
"Length", "ptpip.len", FT_UINT32, BASE_DEC,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptpIP_pktType, {
|
2013-11-25 16:57:43 +00:00
|
|
|
"Packet Type", "ptpip.pktType", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
|
|
|
|
&ptpip_pktType_names_ext, 0, NULL, HFILL }},
|
2013-05-10 01:37:14 +00:00
|
|
|
{ &hf_ptpIP_guid, {
|
|
|
|
"GUID", "ptpip.guid", FT_BYTES, BASE_NONE,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptpIP_name, {
|
2013-12-08 20:03:15 +00:00
|
|
|
"Host Name", "ptpip.name", FT_STRINGZ, STR_UNICODE,
|
2013-05-10 01:37:14 +00:00
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptpIP_version, {
|
|
|
|
"Version", "ptpip.version", FT_STRING, BASE_NONE,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptpIP_connectionNumber, {
|
|
|
|
"Connection Number", "ptpip.connection", FT_UINT32, BASE_DEC,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptpIP_dataPhaseInfo, {
|
|
|
|
"Data Phase Info", "ptpip.phaseinfo", FT_UINT32, BASE_HEX,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
2013-11-25 16:57:43 +00:00
|
|
|
/* PTP layer */
|
|
|
|
/* leaving names with "ptpip" to try and prevent namespace issues. probably changing later. */
|
2013-05-10 01:37:14 +00:00
|
|
|
{ &hf_ptp_opCode, {
|
2015-05-23 02:43:53 +00:00
|
|
|
"Operation Code", "ptpip.opcode", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
|
|
|
|
&ptp_opcode_names_ext, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptp_vendor_opCode, {
|
2013-05-10 01:37:14 +00:00
|
|
|
"Operation Code", "ptpip.opcode", FT_UINT16, BASE_HEX,
|
2015-05-23 02:43:53 +00:00
|
|
|
NULL, 0, NULL, HFILL }},
|
2013-05-10 01:37:14 +00:00
|
|
|
{ &hf_ptp_respCode, {
|
|
|
|
"Response Code", "ptpip.respcode", FT_UINT16, BASE_HEX,
|
|
|
|
VALS(ptp_respcode_names), 0, NULL, HFILL }},
|
2015-05-23 02:43:53 +00:00
|
|
|
{ &hf_ptp_vendor_respCode, {
|
|
|
|
"Response Code", "ptpip.respcode", FT_UINT16, BASE_HEX,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
2013-05-10 01:37:14 +00:00
|
|
|
{ &hf_ptp_eventCode, {
|
|
|
|
"Event Code", "ptpip.eventcode", FT_UINT16, BASE_HEX,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptp_transactionID, {
|
|
|
|
"Transaction ID", "ptpip.transactionID", FT_UINT32, BASE_HEX,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptp_totalDataLength, {
|
|
|
|
"Total Data Length", "ptpip.datalen", FT_UINT64, BASE_DEC_HEX,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
{ &hf_ptp_opCode_param_sessionID, {
|
|
|
|
"Session ID", "ptpip.opcode.param.sessionid", FT_UINT32, BASE_HEX,
|
|
|
|
NULL, 0, NULL, HFILL }},
|
|
|
|
|
|
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_ptpIP,
|
|
|
|
&ett_ptpIP_hdr
|
|
|
|
};
|
|
|
|
|
2015-05-23 02:43:53 +00:00
|
|
|
module_t *ptpIP_module;
|
|
|
|
|
2013-05-10 01:37:14 +00:00
|
|
|
proto_ptpIP = proto_register_protocol("Picture Transfer Protocol Over IP", "PTP/IP", "ptpip");
|
|
|
|
|
|
|
|
proto_register_field_array(proto_ptpIP, hf, array_length(hf));
|
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2015-05-23 02:43:53 +00:00
|
|
|
|
|
|
|
ptpIP_module = prefs_register_protocol(proto_ptpIP, NULL);
|
|
|
|
|
|
|
|
prefs_register_enum_preference(ptpIP_module, "vendor",
|
|
|
|
"Camera vendor",
|
|
|
|
"Properly translates vendor specific opcodes",
|
|
|
|
&pref_vendor, pref_hsp_role, FALSE);
|
|
|
|
|
2013-05-10 01:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void proto_reg_handoff_ptpIP( void ) {
|
|
|
|
|
|
|
|
dissector_handle_t ptpIP_handle;
|
|
|
|
|
2015-12-09 03:49:44 +00:00
|
|
|
/* Use create_dissector_handle() to indicate that dissect_ptpIP()
|
2013-05-10 01:37:14 +00:00
|
|
|
* returns the number of bytes it dissected (or 0 if it thinks the packet
|
|
|
|
* does not belong to PROTONAME).
|
|
|
|
*/
|
|
|
|
|
2015-12-09 03:49:44 +00:00
|
|
|
ptpIP_handle = create_dissector_handle(dissect_ptpIP, proto_ptpIP);
|
2016-10-07 20:25:01 +00:00
|
|
|
dissector_add_uint_with_preference("tcp.port", PTPIP_PORT, ptpIP_handle);
|
2013-05-10 01:37:14 +00:00
|
|
|
}
|
2013-11-25 16:57:43 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
|
|
|
*
|
|
|
|
* Local variables:
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 8
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* End:
|
|
|
|
*
|
|
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
|
|
*/
|