in Firmware/ExpressivePixelsCore/EPXApp_Payload.cpp [94:320]
void CExpressivePixelsApp::PayloadExecute(uint8_t format)
{
LogActiveCommand();
switch (m_PayloadActiveCommand)
{
case PAYLOADCOMMAND_CONNECT_HEADERRQ:
{
EPXString response;
response += JSON_OPENOBJECT;
response += JSON_KEYVALUE_STRINGPAIR_CONTINUED(JSON_STATUS, JSON_SUCCESS);
response += JSON_KEYVALUE_STRINGPAIR_CONTINUED((const char *) JSONKEY_TRANSACTIONID, EPXString((int) m_PayloadActiveTransactionID));
response += JSON_KEYOBJECTOPEN(JSON_DATA);
response += GetDeviceResponseInfo();
response += JSON_CLOSEOBJECT;
response += JSON_CLOSEOBJECT;
// Send response back to host
DataChannelSendResponseJSON(response);
}
break;
case PAYLOADCOMMAND_CLEARDISPLAY:
m_CAppStorage.AutoPlaylistClear();
m_CAnimator.Clear();
break;
case PAYLOADCOMMAND_DISPLAY_BRIGHTNESS:
SetBrightness((uint8_t) m_nPayloadCommandValue);
break;
case PAYLOADCOMMAND_ENUMERATE_ANIMATIONS:
if (m_bAlternateBLEChannel)
{
PPERSISTED_SEQUENCE_LIST pAnimation = m_CAppStorage.FirstStoredSequence();
while (pAnimation != NULL)
{
EPXString payload = EPXString(JSON_OPENOBJECT) + JSON_KEYVALUE_STRINGPAIR("Name", pAnimation->pszName) + JSON_CLOSEOBJECT;
StringProtocolSend((uint8_t *) payload.c_str(), payload.length() + 1);
pAnimation = pAnimation->pNext;
}
EPXString payloadFinal = EPXString(JSON_OPENOBJECT) + JSON_KEYVALUE_STRINGPAIR(JSON_STATUS, JSON_SUCCESS) + JSON_CLOSEOBJECT;
StringProtocolSend((uint8_t *) payloadFinal.c_str(), payloadFinal.length() + 1);
}
else
{
EPXString response;
m_CAppStorage.EnumerateSequencesJSON(response, m_PayloadActiveTransactionID);
DataChannelSendResponseJSON(response); // Send response back to host
}
break;
case PAYLOADCOMMAND_PREVIEW_COLOR:
{
char *pszHex = m_szPayloadCommandValue;
// Stop any running animation
m_CAppStorage.AutoPlaylistClear();
m_CAnimator.Stop();
// Extract triplet hex values from json value
unsigned char byteRed = HexToByte(pszHex, 2);
unsigned char byteGreen = HexToByte(pszHex + 2, 2);
unsigned char byteBlue = HexToByte(pszHex + 4, 2);
uint32_t color = (uint32_t)(((uint32_t)byteRed << 16) | ((uint32_t)byteGreen << 8) | ((uint32_t)byteBlue << 0));
m_CDisplayArray.PreviewColor(color);
}
break;
case PAYLOADCOMMAND_REMOVE_ANIMATION:
m_CAnimator.Clear();
m_CAppStorage.SequenceDelete(m_szPayloadCommandValue);
break;
case PAYLOADCOMMAND_PLAY_STORED_ANIMATION8_BYNAME:
{
char *pszID = m_CAppStorage.SequenceIDFromName(m_szPayloadCommandValue);
if (pszID == NULL)
break;
strcpy(m_szPayloadCommandValue, pszID);
}
// Fall through
case PAYLOADCOMMAND_PLAY_STORED_ANIMATION8 :
case PAYLOADCOMMAND_UPLOAD_ANIMATION8 :
if(m_CAnimator.CanPlay())
{
EXPRESSIVEPIXEL_SEQUENCE sequence;
m_CAppStorage.AutoPlaylistClear();
m_CAnimator.Clear();
if (m_PayloadActiveCommand == PAYLOADCOMMAND_UPLOAD_ANIMATION8)
m_CAppStorage.SequenceWriteClose(&m_StagedAnimation);
if (m_CAppStorage.SequenceRead(m_PayloadActiveCommand == PAYLOADCOMMAND_UPLOAD_ANIMATION8 ? (char *) PLAYNOWID : m_szPayloadCommandValue, &sequence))
{
if (m_nPayloadCommandValue > 0)
sequence.Meta.loopCount = m_nPayloadCommandValue;
if (m_nPayloadCommandValue2)
sequence.runUntilComplete = true;
m_CAnimator.Activate(&sequence);
}
}
break;
case PAYLOADCOMMAND_REQUEST_THUMBNAIL:
{
int width = m_CDisplayArray.Width();
int height = m_CDisplayArray.Height();
uint16_t payloadLength;
BINARY_CHANNEL_RESPONSE *pChannelResponse;
EPX_THUMBNAIL_HEADER *pThumbnailHeader;
uint8_t *pFrameBytes;
payloadLength = sizeof(BINARY_CHANNEL_RESPONSE) + sizeof(EPX_THUMBNAIL_HEADER) + (width * height * DISPLAYARRAY_BYTESPERPIXEL);
uint8_t *pPayload = (uint8_t *) TMALLOC(payloadLength);
if (pPayload != NULL)
{
ACTIVE_ANIMATIONSEQUENCE activeAnimation;
memset(pPayload, 0x00, payloadLength);
pChannelResponse = (BINARY_CHANNEL_RESPONSE *) pPayload;
pChannelResponse->transactionID = m_PayloadActiveTransactionID;
pThumbnailHeader = (EPX_THUMBNAIL_HEADER *)(pChannelResponse + 1);
pFrameBytes = (uint8_t *)(pThumbnailHeader + 1);
memset(&activeAnimation, 0x00, sizeof(activeAnimation));
if (m_CAppStorage.SequenceRead(m_szPayloadCommandValue, &activeAnimation.Sequence, true))
{
activeAnimation.Sequence.pPalette = activeAnimation.Sequence.pRAMPalette;
memcpy(&pThumbnailHeader->guid, &g_displayDesignGUID, sizeof(g_displayDesignGUID));
pThumbnailHeader->utcTimeStamp = activeAnimation.Sequence.utcTimeStamp;
pThumbnailHeader->width = width;
pThumbnailHeader->height = height;
m_CAnimator.RenderFrameToBytes(&activeAnimation, pFrameBytes);
CAnimationManager::ExpressivePixelSequenceFree(&activeAnimation.Sequence);
}
else
payloadLength = sizeof(BINARY_CHANNEL_RESPONSE);
DataChannelSendResponse(pPayload, payloadLength);
TFREE(pPayload);
}
}
break;
case PAYLOADCOMMAND_STORE_ANIMATION8:
m_CAppStorage.AutoPlaylistClear();
m_CAnimator.Clear();
m_CAppStorage.SequenceWriteClose(&m_StagedAnimation);
CAnimationManager::ExpressivePixelSequenceFree(&m_StagedAnimation);
break;
case PAYLOADCOMMAND_UPLOAD_FRAME8:
m_CAppStorage.AutoPlaylistClear();
m_CAnimator.Stop();
if(m_StagedAnimation.pRAMFrames != NULL)
{
m_CAnimator.ShowSingleFrame(m_StagedAnimation.pRAMFrames, m_StagedAnimation.Meta.cbFrames / 3); // 3 bytes per pixel
CAnimationManager::ExpressivePixelSequenceFree(&m_StagedAnimation);
}
break;
case PAYLOADCOMMAND_UPLOAD_PIXEL8:
{
int pixelPosition;
unsigned char byteRed, byteGreen, byteBlue;
uint32_t color;
uint16_t pixelIndex;
if (format == EPX_PROTOCOLFORMAT_BINARY)
{
EPXAPP_PROTOCOL_DEVICEPIXELPAYLOAD *pUploadPixelPayload = (EPXAPP_PROTOCOL_DEVICEPIXELPAYLOAD *) m_szPayloadCommandValue;
pixelIndex = pUploadPixelPayload->pixelIndex;
byteRed = pUploadPixelPayload->pixR;
byteGreen = pUploadPixelPayload->pixG;
byteBlue = pUploadPixelPayload->pixB;
}
else
{
char *pszHex = m_szPayloadCommandValue;
// Extract triplet hex values from json value
byteRed = HexToByte(pszHex, 2);
byteGreen = HexToByte(pszHex + 2, 2);
byteBlue = HexToByte(pszHex + 4, 2);
pixelIndex = m_nPayloadCommandValue;
}
color = (uint32_t)(((uint32_t)byteRed << 16) | ((uint32_t)byteGreen << 8) | ((uint32_t)byteBlue << 0));
m_CAnimator.ShowSinglePixel(pixelIndex, color);
}
break;
case PAYLOADCOMMAND_TTY:
ExecuteTTYCommand();
break;
case PAYLOADCOMMAND_SETDEVICENAME:
strncpy(m_szDeviceName, m_szPayloadCommandValue, sizeof(m_szDeviceName));
DEBUGLOGLN("SETDEVICENAME %s", m_szDeviceName);
CSettings::WriteString((const char *)SETTINGSKEY_DEVICENAME, m_szDeviceName);
m_bRebootOnDisconnect = true;
break;
case PAYLOADCOMMAND_SETKEY:
if (strlen(m_szPayloadCommandValue) == 0)
ClearAESKey();
else if (strlen(m_szPayloadCommandValue) / 2 == EPX_AES_KEY_BYTE_SIZE)
{
char *pszCur = m_szPayloadCommandValue;
int bytePos = 0;
while (*pszCur != 0x00)
{
m_aesKey[bytePos++] = HexToByte(pszCur, 2);
pszCur += 2;
}
DEBUGLOGLN("SETKEY");
CSettings::Write((const char *)SETTINGSKEY_AESKEY, m_aesKey, sizeof(m_aesKey));
}
break;
}
}