Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
715 lines (668 sloc) 14.9 KB
#include "devinfoparser.h"
const char* DevInfoParser::ptpopNames[] PROGMEM =
{
msgUndefined,
msgGetDeviceInfo,
msgOpenSession,
msgCloseSession,
msgGetStorageIDs,
msgGetStorageInfo,
msgGetNumObjects,
msgGetObjectHandles,
msgGetObjectInfo,
msgGetObject,
msgGetThumb,
msgDeleteObject,
msgSendObjectInfo,
msgSendObject,
msgInitiateCapture,
msgFormatStore,
msgResetDevice,
msgSelfTest,
msgSetObjectProtection,
msgPowerDown,
msgGetDevicePropDesc,
msgGetDevicePropValue,
msgSetDevicePropValue,
msgResetDevicePropValue,
msgTerminateOpenCapture,
msgMoveObject,
msgCopyObject,
msgGetPartialObject,
msgInitiateOpenCapture
};
const char* DevInfoParser::mtpopNames[] PROGMEM =
{
msgUndefined,
msgGetObjectPropsSupported,
msgGetObjectPropDesc,
msgGetObjectPropValue,
msgSetObjectPropValue,
msgGetObjectPropList,
msgSetObjectPropList,
msgGetInterdependentPropDesc,
msgSendObjectPropList
};
const char* DevInfoParser::ptpevNames[] PROGMEM =
{
msgUndefined,
msgCancelTransaction,
msgObjectAdded,
msgObjectRemoved,
msgStoreAdded,
msgStoreRemoved,
msgDevicePropChanged,
msgObjectInfoChanged,
msgDeviceInfoChanged,
msgRequestObjectTransfer,
msgStoreFull,
msgDeviceReset,
msgStorageInfoChanged,
msgCaptureComplete,
msgUnreportedStatus
};
const char* DevInfoParser::mtpevNames[] PROGMEM =
{
msgUndefined,
msgObjectPropChanged,
msgObjectPropDescChanged,
msgObjectReferencesChanged
};
const char* DevInfoParser::ptpprNames[] PROGMEM =
{
msgUndefined,
msgBatteryLevel,
msgFunctionalMode,
msgImageSize,
msgCompressionSetting,
msgWhiteBalance,
msgRGBGain,
msgFNumber,
msgFocalLength,
msgFocusDistance,
msgFocusMode,
msgExposureMeteringMode,
msgFlashMode,
msgExposureTime,
msgExposureProgramMode,
msgExposureIndex,
msgExposureBiasCompensation,
msgDateTime,
msgCaptureDelay,
msgStillCaptureMode,
msgContrast,
msgSharpness,
msgDigitalZoom,
msgEffectMode,
msgBurstNumber,
msgBurstInterval,
msgTimelapseNumber,
msgTimelapseInterval,
msgFocusMeteringMode,
msgUploadURL,
msgArtist,
msgCopyrightInfo
};
const char* DevInfoParser::mtpprNames[] PROGMEM =
{
msgUndefined,
msgSynchronization_Partner,
msgDevice_Friendly_Name,
msgVolume,
msgSupportedFormatsOrdered,
msgDeviceIcon,
msgSession_Initiator_Version_Info,
msgPerceived_Device_Type,
msgPlayback_Rate,
msgPlayback_Object,
msgPlayback_Container
};
const char* DevInfoParser::acNames[] PROGMEM =
{
msgUndefined,
msgAssociation,
msgScript,
msgExecutable,
msgText,
msgHTML,
msgDPOF,
msgAIFF,
msgWAV,
msgMP3,
msgAVI,
msgMPEG,
msgASF,
msgQT
};
const char* DevInfoParser::imNames[] PROGMEM =
{
msgUndefined,
msgEXIF_JPEG,
msgTIFF_EP,
msgFlashPix,
msgBMP,
msgCIFF,
msgUndefined_0x3806,
msgGIF,
msgJFIF,
msgPCD,
msgPICT,
msgPNG,
msgUndefined_0x380C,
msgTIFF,
msgTIFF_IT,
msgJP2,
msgJPX,
};
DevInfoParser::DevInfoParser() :
nStage(0),
strByteCountDown(0),
waStage(0),
waLenCountDown(0),
waByteCountDown(0),
fmByteCountDown(0),
idVendor(0)
{
for (uint8_t i=0; i<4; i++) waLen[i];
waWord.word = 0;
fmBytes[0] = 0;
fmBytes[1] = 0;
};
bool DevInfoParser::PrintFunctMode(uint8_t **pp, uint16_t &count)
{
if (!count)
return true;
if (!fmByteCountDown)
fmByteCountDown = 2;
for (; fmByteCountDown && count; fmByteCountDown--, count--, (*pp)++)
fmBytes[fmByteCountDown & 1] = (**pp);
if (fmByteCountDown)
return false;
Notify(PSTR("Func.Mode:\t0x")); Serial.println((uint16_t)fmBytes, HEX);
return true;
}
void DevInfoParser::PrintOperation(uint16_t op)
{
bool bResult = false;
Serial.print(op, HEX);
Notify(msgTab);
switch (((op >> 8) & 0xFF))
{
case 0x10:
bResult = PrintPTPOperation(op);
break;
case 0x98:
bResult = PrintMTPOperation(op);
break;
default:
switch (idVendor)
{
case PTP_VENDOR_MICROSOFT:
case PTP_VENDOR_CANON:
if ((bResult = PrintPSOperation(op)))
break;
bResult = PrintEOSOperation(op);
break;
default:
Notify(msgVendorDefined);
bResult = true;
}
}
if (!bResult)
Notify(msgVendorDefined);
Notify(msgCRLF);
}
bool DevInfoParser::PrintPTPOperation(uint16_t op)
{
if ((op & 0xFF) <= (PTP_OC_InitiateOpenCapture & 0xFF))
{
Notify((char*)pgm_read_word(&ptpopNames[(op & 0xFF)]));
return true;
}
return false;
}
bool DevInfoParser::PrintMTPOperation(uint16_t op)
{
if ((op & 0xFF) <= (MTP_OC_SendObjectPropList & 0xFF))
Notify((char*)pgm_read_word(&mtpopNames[(op & 0xFF)]));
else
{
switch (op)
{
case MTP_OC_GetObjectReferences:
Notify(msgGetObjectReferences);
break;
case MTP_OC_SetObjectReferences:
Notify(msgSetObjectReferences);
break;
case MTP_OC_Skip:
Notify(msgSkip);
break;
default:
return false;
}
}
return true;
}
bool DevInfoParser::PrintPSOperation(uint16_t op)
{
const char* msg;
switch (op)
{
case PTP_OC_PS_GetObjectSize:
msg = msgPS_GetObjectSize;
break;
case PTP_OC_PS_StartShootingMode:
msg = msgPS_StartShootingMode;
break;
case PTP_OC_PS_EndShootingMode:
msg = msgPS_EndShootingMode;
break;
case PTP_OC_PS_ViewfinderOn:
msg = msgPS_ViewfinderOn;
break;
case PTP_OC_PS_ViewfinderOff:
msg = msgPS_ViewfinderOff;
break;
case PTP_OC_PS_ReflectChanges:
msg = msgPS_ReflectChanges;
break;
case PTP_OC_PS_CheckEvent:
msg = msgPS_CheckEvent;
break;
case PTP_OC_PS_FocusLock:
msg = msgPS_FocusLock;
break;
case PTP_OC_PS_FocusUnlock:
msg = msgPS_FocusUnlock;
break;
case PTP_OC_PS_InitiateCaptureInMemory:
msg = msgPS_InitiateCaptureInMemory;
break;
case PTP_OC_PS_GetPartialObject:
msg = msgPS_GetPartialObject;
break;
case PTP_OC_PS_GetViewfinderImage:
msg = msgPS_GetViewfinderImage;
break;
case PTP_OC_PS_GetChanges:
msg = msgPS_GetChanges;
break;
case PTP_OC_PS_GetFolderEntries:
msg = msgPS_GetFolderEntries;
break;
default:
return false;
}
Notify(msg);
return true;
}
bool DevInfoParser::PrintEOSOperation(uint16_t op)
{
const char *msg;
switch (op)
{
case PTP_OC_EOS_GetStorageIDs:
msg = msgEOS_GetStorageIDs;
break;
case PTP_OC_EOS_GetStorageInfo:
msg = msgEOS_GetStorageInfo;
break;
case PTP_OC_EOS_GetObject:
msg = msgEOS_GetObject;
break;
case PTP_OC_EOS_GetDeviceInfo:
msg = msgEOS_GetDeviceInfo;
break;
case PTP_OC_EOS_GetObjectIDs:
msg = msgEOS_GetObjectIDs;
break;
case PTP_OC_EOS_Capture:
msg = msgEOS_Capture;
break;
case PTP_OC_EOS_SetDevicePropValue:
msg = msgEOS_SetDevicePropValue;
break;
case PTP_OC_EOS_SetPCConnectMode:
msg = msgEOS_SetPCConnectMode;
break;
case PTP_OC_EOS_SetExtendedEventInfo:
msg = msgEOS_SetExtendedEventInfo;
break;
case PTP_OC_EOS_GetEvent:
msg = msgEOS_GetEvent;
break;
case PTP_OC_EOS_GetLiveViewPicture:
msg = msgEOS_GetLiveViewPicture;
break;
case PTP_OC_EOS_MoveFocus:
msg = msgEOS_MoveFocus;
break;
default:
return false;
}
Notify(msg);
return true;
}
void DevInfoParser::PrintEvent(uint16_t op)
{
Serial.print(op, HEX);
Notify(msgTab);
if ((((op >> 8) & 0xFF) == 0x40) && ((op & 0xFF) <= (PTP_EC_UnreportedStatus & 0xFF)))
Notify((char*)pgm_read_word(&ptpevNames[(op & 0xFF)]));
else
if ((((op >> 8) & 0xFF) == 0xC8) && ((op & 0xFF) <= (MTP_EC_ObjectReferencesChanged & 0xFF)))
Notify((char*)pgm_read_word(&mtpevNames[(op & 0xFF)]));
else
Notify(msgVendorDefined);
Notify(msgCRLF);
}
void DevInfoParser::PrintDevProp(uint16_t op)
{
Serial.print(op, HEX);
Notify(msgTab);
if ((((op >> 8) & 0xFF) == 0x50) && ((op & 0xFF) <= (PTP_DPC_CopyrightInfo & 0xFF)))
Notify((char*)pgm_read_word(&ptpprNames[(op & 0xFF)]));
else
if (((op >> 8) & 0xFF) == 0xD4)
{
if ( (op & 0xFF) <= (MTP_DPC_Perceived_Device_Type & 0xFF) )
Notify((char*)pgm_read_word(&mtpprNames[(op & 0xFF)]));
else
{
switch (op)
{
case MTP_DPC_Playback_Rate:
Notify(msgPlayback_Rate);
break;
case MTP_DPC_Playback_Object:
Notify(msgPlayback_Object);
break;
case MTP_DPC_Playback_Container:
Notify(msgPlayback_Container);
break;
default:
Notify(msgVendorDefined);
}
}
}
else
Notify(msgVendorDefined);
Notify(msgCRLF);
}
void DevInfoParser::PrintFormat(uint16_t op)
{
Serial.print(op, HEX);
Notify(msgTab);
if ((((op >> 8) & 0xFF) == 0x30) && ((op & 0xFF) <= (PTP_OFC_QT & 0xFF)))
Notify((char*)pgm_read_word(&acNames[(op & 0xFF)]));
else
if ((((op >> 8) & 0xFF) == 0x38) && ((op & 0xFF) <= (PTP_OFC_JPX & 0xFF)))
Notify((char*)pgm_read_word(&imNames[(op & 0xFF)]));
else
{
switch (op)
{
case MTP_OFC_Undefined_Firmware:
Notify(msgUndefined_Firmware);
break;
case MTP_OFC_Windows_Image_Format:
Notify(msgWindows_Image_Format);
break;
case MTP_OFC_Undefined_Audio:
Notify(msgUndefined_Audio);
break;
case MTP_OFC_WMA:
Notify(msgWMA);
break;
case MTP_OFC_OGG:
Notify(msgOGG);
break;
case MTP_OFC_AAC:
Notify(msgAAC);
break;
case MTP_OFC_Audible:
Notify(msgAudible);
break;
case MTP_OFC_FLAC:
Notify(msgFLAC);
break;
case MTP_OFC_Undefined_Video:
Notify(msgUndefined_Video);
break;
case MTP_OFC_WMV:
Notify(msgWMV);
break;
case MTP_OFC_MP4_Container:
Notify(msgMP4_Container);
break;
case MTP_OFC_MP2:
Notify(msgMP2);
break;
case MTP_OFC_3GP_Container:
Notify(msg3GP_Container);
break;
default:
Notify(msgVendorDefined);
}
}
Notify(msgCRLF);
}
bool DevInfoParser::PrintVendor(uint8_t **pp, uint16_t &count)
{
Notify(PSTR("Vendor Ext. ID:\t0x"));
Serial.print(*((uint32_t*)*pp),HEX);
switch (*((uint32_t*)*pp))
{
case PTP_VENDOR_EASTMAN_KODAK:
Notify(PSTR("(Eastman Kodak)"));
break;
case PTP_VENDOR_SEIKO_EPSON:
Notify(PSTR("(Seiko Epson)"));
break;
case PTP_VENDOR_AGILENT:
Notify(PSTR("(Agilent)"));
break;
case PTP_VENDOR_POLAROID:
Notify(PSTR("(Polaroid)"));
break;
case PTP_VENDOR_AGFA_GEVAERT:
Notify(PSTR("(AGFA)"));
break;
case PTP_VENDOR_MICROSOFT:
Notify(PSTR("(Microsoft)"));
break;
case PTP_VENDOR_EQUINOX:
Notify(PSTR("(Equinox)"));
break;
case PTP_VENDOR_VIEWQUEST:
Notify(PSTR("(ViewQuest)"));
break;
case PTP_VENDOR_STMICROELECTRONICS:
Notify(PSTR("(StMicroelectronics)"));
break;
case PTP_VENDOR_NIKON:
Notify(PSTR("(Nikon)"));
break;
case PTP_VENDOR_CANON:
Notify(PSTR("(Canon)"));
break;
case PTP_VENDOR_FOTONATION:
Notify(PSTR("(FotoNation)"));
break;
case PTP_VENDOR_PENTAX:
Notify(PSTR("(Pentax)"));
break;
case PTP_VENDOR_FUJI:
Notify(PSTR("(Fuji)"));
break;
default:
Notify(PSTR("(Unknown)"));
}
Notify(msgCRLF);
*pp += 4; count -= 4;
return true;
}
bool DevInfoParser::PrintString(uint8_t **pp, uint16_t &count)
{
if (!count)
return true;
if ( !strByteCountDown )
{
if ( !(**pp) )
{
(*pp) ++;
count --;
return true;
}
strByteCountDown = ((**pp) << 1);
(*pp) ++;
count --;
}
for (; strByteCountDown && count; strByteCountDown--, count--, (*pp)++)
{
if ( !(strByteCountDown & 1) && ((**pp) > 0))
Serial.print((unsigned char)(**pp));
}
return (strByteCountDown == 0);
}
bool DevInfoParser::PrintWordArray(uint8_t **pp, uint16_t &count, PRINTFUNC pf = NULL)
{
switch (waStage)
{
case 0:
if (!waLenCountDown)
waLenCountDown = 4;
for (; waLenCountDown && count; waLenCountDown--, count--, (*pp)++)
waLen[4-waLenCountDown] = (**pp);
if (waLenCountDown)
return false;
waStage ++;
case 1:
for (waByteCountDown = (waByteCountDown) ? waByteCountDown : ((*((uint32_t*)waLen) << 1));
waByteCountDown && count; waByteCountDown--, count--, (*pp)++)
{
if (waByteCountDown & 1)
{
waWord.bytes[1] = (**pp);
if ( pf )
(this->*pf)(waWord.word);
else
Serial.println (waWord.word, HEX);
}
else
waWord.bytes[0] = (**pp);
}
if (waByteCountDown)
return false;
}
waStage = 0;
return true;
}
void DevInfoParser::Parse(const uint16_t len, const uint8_t *pbuf, const uint32_t &offset)
{
uint16_t count = (uint16_t)len;
uint8_t *p = (uint8_t*)pbuf;
switch (nStage)
{
case 0:
// Skip PTP container header
p += 12; count -=12;
nStage ++;
case 1:
Notify(PSTR("\r\nStd.Ver.:\t0x")); Serial.println(*(uint16_t*)p, DEC);
p += 2; count -= 2;
idVendor = *((uint32_t*)p);
PrintVendor(&p, count);
Notify(PSTR("\r\nVend.Ext.Ver.:\t0x")); Serial.println(*((uint16_t*)p), HEX);
p += 2; count -=2;
nStage ++;
case 2:
// Vendor extension description
//if (*p)
{
if (!PrintString(&p, count))
return;
Notify(msgCRLF);
}
nStage ++;
case 3:
// Functional mode
if (!PrintFunctMode(&p, count))
return;
nStage ++;
case 4:
// Operations Supported
Notify(PSTR("\r\nOperations supported:\r\n"));
nStage++;
case 5:
if (!PrintWordArray(&p, count, &DevInfoParser::PrintOperation))
return;
nStage ++;
case 6:
// Events Supported
Notify(PSTR("\r\nEvents supported:\r\n"));
nStage ++;
case 7:
if (!PrintWordArray(&p, count, &DevInfoParser::PrintEvent))
return;
nStage ++;
case 8:
// Device Properties Supported
Notify(PSTR("\r\nDevice properties supported:\r\n"));
nStage ++;
case 9:
if (!PrintWordArray(&p, count, &DevInfoParser::PrintDevProp))
return;
nStage ++;
case 10:
// Capture formats
Notify(PSTR("\r\nCapture formats:\r\n"));
nStage ++;
case 11:
if (!PrintWordArray(&p, count, &DevInfoParser::PrintFormat))
return;
nStage ++;
case 12:
// Image Formats
Notify(PSTR("\r\nImage Formats:\r\n"));
nStage ++;
case 13:
if (!PrintWordArray(&p, count, &DevInfoParser::PrintFormat))
return;
nStage ++;
case 14:
// Manufacturer
Notify(PSTR("\r\nManufacturer:\t"));
nStage ++;
case 15:
if (!PrintString(&p, count))
return;
nStage ++;
case 16:
// Model
Notify(PSTR("\r\nModel:\t\t"));
nStage ++;
case 17:
if (!PrintString(&p, count))
return;
nStage ++;
case 18:
// Device version
Notify(PSTR("\r\nDevice ver.:\t"));
nStage ++;
case 19:
if (!PrintString(&p, count))
return;
nStage ++;
case 20:
// Serial number
Notify(PSTR("\r\nSerial num.:\t"));
nStage ++;
case 21:
if (!PrintString(&p, count))
return;
Notify(PSTR("\r\n\r\n"));
//nStage = 0;
}
}