/*
* Video On Demand Samples
*
* Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* You may also obtain this software under a propriety license from Microchip.
* Please contact Microchip for further information.
*
*/
#include "SafeVector.h"
#include "Console.h"
#include "ScriptXml.h"
#define TAG_SCRIPT ((xmlChar *)"script")
#define TAG_ACTION ((xmlChar *)"action")
#define TAG_NAME ((xmlChar *)"name")
#define TAG_TYPE ((xmlChar *)"type")
#define TAG_FBLOCK_ID_HEX ((xmlChar *)"fblock_id_hex")
#define TAG_FUNCTION_ID_HEX ((xmlChar *)"function_id_hex")
#define TAG_OP_TYPE_REQUEST_HEX ((xmlChar *)"op_type_request_hex")
#define TAG_OP_TYPE_RESPONSE_HEX ((xmlChar *)"op_type_response_hex")
#define TAG_PAYLOAD_HEX ((xmlChar *)"payload_hex")
#define TAG_PAUSE_MS ((xmlChar *)"pause_ms")
#define VAL_SEND_MCM ((char*)"SEND_MCM")
#define VAL_PAUSE ((char*)"PAUSE")
#define XML_STRCMP(x,y) (strcmp(reinterpret_cast< const char* >(x), reinterpret_cast< const char* >(y)) == 0)
CSciptXml::CSciptXml( const char *szFile ) : CXml( szFile )
{
}
CSciptXml::CSciptXml( const char *szBuffer, uint32_t nBufferLen ) : CXml( szBuffer, nBufferLen )
{
}
bool CSciptXml::GetScripts( CSafeVector &allChannels )
{
xmlChar szTmp[XML_DEFAULT_VALUE_LEN];
bool success = false;
CXml Xml( *( ( CXml * )this ) );
success = Xml.SetToTopNode();
while( success && Xml.FindNode( TAG_ACTION ) )
{
ConsolePrintf( PRIO_LOW, BLUE"--NEW ACTION--"RESETCOLOR"\n" );
CScript *script = new CScript();
if( NULL == script )
break;
szTmp[0] = '\0';
success &= Xml.GetChildValue( TAG_NAME, szTmp, XML_DEFAULT_VALUE_LEN );
if( success )
{
ConsolePrintf( PRIO_LOW, BLUE"Name: '%s'"RESETCOLOR"\n", szTmp );
int nameLen = sizeof( xmlChar ) * ( xmlStrlen( szTmp ) + 1 );
if( nameLen >= MAX_SCRIPT_NAME_LENGTH )
nameLen = MAX_SCRIPT_NAME_LENGTH - 1;
memcpy( script->scriptName, szTmp, nameLen );
script->scriptName[nameLen] = '\0'; //Terminate string in any case
}
szTmp[0] = '\0';
success &= Xml.GetChildValue( TAG_TYPE, szTmp );
if( success )
{
ConsolePrintf( PRIO_LOW, BLUE"Type: %s"RESETCOLOR"\n", szTmp );
if( XML_STRCMP(szTmp, VAL_SEND_MCM) )
{
script->scriptType = SCRIPT_MCM_SEND;
}
else if( XML_STRCMP(szTmp, VAL_PAUSE) )
{
script->scriptType = SCRIPT_PAUSE;
}
else
{
//Be tolerant to new types
ConsolePrintf( PRIO_ERROR, YELLOW"CSciptXml: Ignoring unknown TYPE:'%s'"RESETCOLOR"\n", szTmp );
delete script;
Xml.FindNextNode();
continue;
}
}
if( SCRIPT_MCM_SEND == script->scriptType )
{
szTmp[0] = '\0';
success &= Xml.GetChildValue( TAG_FBLOCK_ID_HEX, szTmp, XML_DEFAULT_VALUE_LEN );
if( success )
{
script->fblockId = ConvertToInt( szTmp );
ConsolePrintf( PRIO_LOW, BLUE"FBlock-ID: '%s=%d'"RESETCOLOR"\n", szTmp, script->fblockId );
}
szTmp[0] = '\0';
success &= Xml.GetChildValue( TAG_FUNCTION_ID_HEX, szTmp, XML_DEFAULT_VALUE_LEN );
if( success )
{
script->functionId = ConvertToInt( szTmp );
ConsolePrintf( PRIO_LOW, BLUE"Function-ID: '%s=%d'"RESETCOLOR"\n", szTmp, script->functionId );
}
szTmp[0] = '\0';
success &= Xml.GetChildValue( TAG_OP_TYPE_REQUEST_HEX, szTmp,
XML_DEFAULT_VALUE_LEN );
if( success )
{
script->opTypeRequest = ConvertToInt( szTmp );
ConsolePrintf( PRIO_LOW, BLUE"OP-Type Request: '%s=%d'"RESETCOLOR"\n", szTmp, script->opTypeRequest );
}
szTmp[0] = '\0';
if( Xml.GetChildValue( TAG_OP_TYPE_RESPONSE_HEX, szTmp,
XML_DEFAULT_VALUE_LEN ) )
{
script->opTypeResponse = ConvertToInt( szTmp );
ConsolePrintf( PRIO_LOW, BLUE"OP-Type Response: '%s=%d'"RESETCOLOR"\n", szTmp,
script->opTypeResponse );
}
else
{
script->opTypeResponse = 0xFF;
ConsolePrintf( PRIO_LOW, BLUE"OP-Type Response was not defined"RESETCOLOR"\n" );
}
szTmp[0] = '\0';
//Payload is optional
if( Xml.GetChildValue( TAG_PAYLOAD_HEX, szTmp, XML_DEFAULT_VALUE_LEN ) )
{
ConsolePrintf( PRIO_LOW, BLUE"Payload: '%s'"RESETCOLOR"\n", szTmp );
StorePayload( szTmp, script );
}
}
else if( SCRIPT_PAUSE == script->scriptType )
{
szTmp[0] = '\0';
success &= Xml.GetChildValue( TAG_PAUSE_MS, szTmp, XML_DEFAULT_VALUE_LEN );
if( success )
{
script->pauseInMillis = strtol( ( char * )szTmp, NULL, 10 );
ConsolePrintf( PRIO_LOW, BLUE"FBlock-ID: '%s=%d'"RESETCOLOR"\n", szTmp, script->fblockId );
}
}
if( success )
{
allChannels.PushBack( script );
}
else
{
delete script;
}
Xml.FindNextNode();
}
return success;
}
void CSciptXml::StorePayload( xmlChar *xString, CScript *script )
{
char *cString = ( char * )xString; //Convertion may be needed..
script->payloadLength = 0;
for( uint32_t i = 0; i < strlen( cString ); i++ )
{
if( cString[i] >= 65 && cString[i] <= 90 )
{
//convert upper case to lower case
cString[i] += 32;
}
}
char *tkPtr;
char *token = strtok_r( cString, " ,.-", &tkPtr );
while( NULL != token )
{
if( script->payloadLength >= MAX_PAYLOAD_LENGTH )
{
ConsolePrintf( PRIO_ERROR,
"CSciptXml::ConvertToByteArray, MAX_PAYLOAD_LENGTH is defined too low. Please increase value!" );
break;
}
script->payload[script->payloadLength++] = strtol( token, NULL, 16 );
token = strtok_r( NULL, " ,.-", &tkPtr );
}
}