void CExpressivePixelsApp::PayloadParseBinary()

in Firmware/ExpressivePixelsCore/EPXApp_Payload_Binary.cpp [10:127]


void CExpressivePixelsApp::PayloadParseBinary(uint8_t data)
{
	if (!m_bDynamicPayloadFilling && m_PayloadBinaryFillPos < MAX_COMMAND_VALUE)
		m_szPayloadCommandValue[m_PayloadBinaryFillPos++] = data;	
	
	if (m_PayloadActiveCommand == 0)
	{	
		// Wait for enough of the protocol header to be received
		if (m_PayloadBinaryFillPos >= sizeof(EPXAPP_PROTOCOL_HEADER))
		{
			// Start tracking the payload command type
			EPXAPP_PROTOCOL_HEADER *pHeader = (EPXAPP_PROTOCOL_HEADER *) m_szPayloadCommandValue;
			m_PayloadActiveCommand = pHeader->command;
		}
	}
	else
	{
		if (m_bDynamicPayloadFilling)
		{
			switch (m_PayloadActiveCommand)
			{
			case PAYLOADCOMMAND_UPLOAD_FRAME8:
				if (m_StagedAnimation.pRAMFrames != NULL && m_PayloadParseCommandSequenceFillPos < m_StagedAnimation.Meta.cbFrames)
					m_StagedAnimation.pRAMFrames[m_PayloadParseCommandSequenceFillPos++] = data;
				break;
						
			case PAYLOADCOMMAND_STORE_ANIMATION8:
				{
					EPXAPP_PROTOCOL_ANIMATIONPAYLOAD *pAnimationPayload = (EPXAPP_PROTOCOL_ANIMATIONPAYLOAD *) m_szPayloadCommandValue;

					m_CAppStorage.SequenceWriteData(&m_StagedAnimation, &data, sizeof(data));						
					m_animationPayloadStateMachine.sectionBytesRemaining--;
					if (m_animationPayloadStateMachine.sectionBytesRemaining == 0)
					{
						switch (m_animationPayloadStateMachine.state)
						{										
						case ANIMATIONPAYLOAD_STATE_NAME:
							// Finalize string
							m_StagedAnimation.pszName[m_animationPayloadStateMachine.sectionFillPos++] = data;
							m_StagedAnimation.pszName[m_animationPayloadStateMachine.sectionFillPos] = 0x00;
							
							m_animationPayloadStateMachine.state = ANIMATIONPAYLOAD_STATE_PALETTE;
							m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_PALLETESIZE, (uint8_t *) &pAnimationPayload->paletteSize, sizeof(pAnimationPayload->paletteSize));
							m_CAppStorage.SequenceWriteToken(&m_StagedAnimation, SEQUENCETOKEN_PALLETEBYTES);
							m_animationPayloadStateMachine.sectionFillPos = 0;
							m_animationPayloadStateMachine.sectionBytesRemaining = pAnimationPayload->paletteSize * sizeof(PALETTE_ENTRY);
							break;
										
						case ANIMATIONPAYLOAD_STATE_PALETTE:
							m_animationPayloadStateMachine.state = ANIMATIONPAYLOAD_STATE_FRAMES;
							m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_FRAMESBYTELEN, (uint8_t *) &pAnimationPayload->framesPayloadSize, sizeof(pAnimationPayload->framesPayloadSize));
							m_CAppStorage.SequenceWriteToken(&m_StagedAnimation, SEQUENCETOKEN_FRAMESBYTES);
							m_animationPayloadStateMachine.sectionFillPos = 0;
							m_animationPayloadStateMachine.sectionBytesRemaining = pAnimationPayload->framesPayloadSize;
							break;
						}
					}
					else
					{
						switch (m_animationPayloadStateMachine.state)
						{										
							case ANIMATIONPAYLOAD_STATE_NAME:
								m_StagedAnimation.pszName[m_animationPayloadStateMachine.sectionFillPos++] = data;
								break;
						}
					}
				}
				break;
			}			
		}
		else
		{			
			// Header has been received, now track the payload data
			switch(m_PayloadActiveCommand)
			{
			case PAYLOADCOMMAND_UPLOAD_FRAME8:
				if (!m_bDynamicPayloadFilling && m_PayloadBinaryFillPos >= sizeof(EPXAPP_PROTOCOL_DEVICEFRAMEPAYLOAD))
				{
					EPXAPP_PROTOCOL_DEVICEFRAMEPAYLOAD *pFramePayload = (EPXAPP_PROTOCOL_DEVICEFRAMEPAYLOAD *) m_szPayloadCommandValue;				
					m_StagedAnimation.Meta.cbFrames = (pFramePayload->width * pFramePayload->height * 3);
					m_StagedAnimation.pRAMFrames = (uint8_t *) TMALLOC(m_StagedAnimation.Meta.cbFrames);
					m_PayloadParseCommandSequenceFillPos = 0;
					m_bDynamicPayloadFilling = true;
				}			
				break;
		
			case PAYLOADCOMMAND_STORE_ANIMATION8:
				if (!m_bDynamicPayloadFilling && m_PayloadBinaryFillPos >= sizeof(EPXAPP_PROTOCOL_ANIMATIONPAYLOAD))
				{
					EPXAPP_PROTOCOL_ANIMATIONPAYLOAD *pAnimationPayload = (EPXAPP_PROTOCOL_ANIMATIONPAYLOAD *) m_szPayloadCommandValue;
							
					CompletionTrackingEnable();
					uint8_t guidLen = sizeof(pAnimationPayload->id);
					BytesToHex(pAnimationPayload->id, sizeof(pAnimationPayload->id), m_StagedAnimation.szID, sizeof(m_StagedAnimation.szID));					
					m_StagedAnimation.utcTimeStamp = pAnimationPayload->utcTimestamp;
					
					guidLen = strlen(m_StagedAnimation.szID);
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_GUIDLEN, &guidLen, sizeof(guidLen));
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_GUID, (uint8_t *) m_StagedAnimation.szID, guidLen);
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_LOOPCOUNT, &pAnimationPayload->loopCount, sizeof(pAnimationPayload->loopCount));
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_FRAMERATE, &pAnimationPayload->frameRate, sizeof(pAnimationPayload->frameRate));
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_FRAMECOUNT, (uint8_t *) &pAnimationPayload->frameCount, sizeof(pAnimationPayload->frameCount));
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_UTCTIMESTAMP, (uint8_t *) &pAnimationPayload->utcTimestamp, sizeof(pAnimationPayload->utcTimestamp));
																
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_NAMELEN, &pAnimationPayload->nameLength, sizeof(pAnimationPayload->nameLength));
					m_animationPayloadStateMachine.sectionBytesRemaining = pAnimationPayload->nameLength;							
					m_StagedAnimation.pszName = (char *) TMALLOC(pAnimationPayload->nameLength + 1);					
					m_CAppStorage.SequenceWriteSection(&m_StagedAnimation, SEQUENCETOKEN_NAME);
									
					// Kick of the state machine for the remainder of the payload
					m_animationPayloadStateMachine.state = ANIMATIONPAYLOAD_STATE_NAME;
					m_bDynamicPayloadFilling = true;
				}
				break;
			}		
		}
	}
}