/*
 * 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 2 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 <http://www.gnu.org/licenses/>.
 *
 * You may also obtain this software under a propriety license from Microchip.
 * Please contact Microchip for further information.
 *
 */

/*----------------------------------------------------------*/
/*! \file
 *  \brief  This file contains the CVodXml, CChannelConfiguration and the CSocketConfiguration classes.
 */
/*----------------------------------------------------------*/
#ifndef _VODXML_H_
#define _VODXML_H_

#include <stdint.h>
#include <stdbool.h>
#include <Types.h>
#include "Xml.h"

typedef enum SocketPort_tag
{
    PORT_UNKNOWN,
    PORT_I2C,
    PORT_I2S,
    PORT_PCIE,
    PORT_MLB,
    PORT_MOST,
    PORT_TSI,
    PORT_USB
} SocketPort_t;

/*----------------------------------------------------------*/
/*!
 * \brief Storage class to store I2S related informations
 */

/*----------------------------------------------------------*/
class CI2SConfiguration
{
public:
    ///I2S Clock drive mode
    V1I2SPortClkDriveMode_t portClkDriveModeV1;

    ///I2S Streaming port mode
    V1I2SStreamingPortMode_t portOptionV1;

    ///I2S Streaming data format
    V1I2SStreamingDataFormat_t streamingDataFormatV1;

    ///I2S Stream Pin ID
    V1I2SPin_t pinV1;

    ///I2S Port option
    V3I2SPortOption_t portOption;

    ///I2S  Clock mode
    V3I2SClockMode_t clockMode;

    ///I2S Delay option
    V3I2SDelayMode_t delayMode;

    ///I2S Port speed in mulitple of MOST base clock (FS)
    V3I2SPortSpeed_t portSpeed;

    ///I2S Data Alignment
    V3I2SAlignment_t alignment;

    ///I2S Stream Pin ID
    V3I2SPin_t pin;

    CI2SConfiguration() : portClkDriveModeV1( V1I2sClockModeUnknown ),
                          streamingDataFormatV1( V1I2sDataFormatUnknown ), pinV1( V1I2sInvalidPin ),
                          portOption( V3I2SOptionUnknown ), clockMode( V3I2SClockModeUnknown ),
                          delayMode( V3I2SDelayUnknown ), portSpeed( V3I2SSpeedUnknown ),
                          alignment( V3I2SAlignUnknown ), pin( V3I2SInvalidPin )
    {
    }
};

/*----------------------------------------------------------*/
/*!
 * \brief Storage class to store TSI related informations (only available on OS81110)
 */

/*----------------------------------------------------------*/
class CTsiConfigurationV1
{
public:
    ///TSI port instance
    V1TsiPortInstance_t tsiPortInstance;

    ///I2S Streaming port mode
    V1TsiPortMode tsiPortMode;

    CTsiConfigurationV1() : tsiPortInstance(V1TsiPortInstanceNotSet), tsiPortMode(V1TsiPortModeNotSet)
    {
    }
};

/*----------------------------------------------------------*/
/*!
 * \brief Storage class to store all socket related informations. This class will be used inside
 *        the CChannelConfiguration class.
 */

/*----------------------------------------------------------*/
class CSocketConfiguration
{
public:
    ///Determines the type of used Application Interface Module (Linux Driver API)
    AimType_t aimType;

    /// Determines the used INIC port
    SocketPort_t port;

    /// Determines the used MOST data type
    EPDataType_t type;

    /// Determines the offset of current socket is splitted in case of usage of Splitter or Combiner
    /// The value in case Splitter or Combiner are not used, this value is 0xFFFFFFFF.
    uint32_t splittedOffset;

    /// Determines the used amount of bytes used for this configuration
    uint32_t blockWidth;

    /// Determines the used address. This value is generic and has to be interpreted for the used INIC port.
    uint32_t address;

    /// (optional) Determines the amount of buffers used in the driver.
    uint32_t amountOfBuffers;

    /// (optional) Determines the size of a single buffer used in the driver.
    uint32_t bufferSize;

    /// (optional) Determines the amount of transmitted packets inside of one USB frame.
    uint32_t packetsPerTransaction;

    /// (optional) Determines the width of a subbuffer.
    uint32_t subbufferSize;

    /// (optional) In case of I2C port, this class holds the corresponding informations
    CI2SConfiguration i2sConfig;
    
    /// (optional) In case of TSI port, this class holds the corresponding informations
    CTsiConfigurationV1 tsiConfig;

    CSocketConfiguration() : aimType( AIM_UNKNOWN ), port( PORT_UNKNOWN ), type( EP_Unknown ),
                             splittedOffset( 0xFFFFFFFF ), blockWidth( 0xFFFFFFFF ), address( 0xFFFFFFFF ),
                             amountOfBuffers( 32 ), bufferSize( 8192 ), packetsPerTransaction( 2 ),
                             subbufferSize( 188 )
    {
    }
};

/*----------------------------------------------------------*/
/*!
 * \brief Storage class to store all channel related informations. This class will be returned by
 *        the CVodXml class.
 */

/*----------------------------------------------------------*/
class CChannelConfiguration
{
public:
    /// Determines the device type as specified in the configuration XML file and found in the group address configuration.
    uint32_t deviceType;

    /// Determines the used channel id, as specified in the configuration XML file.
    uint32_t channelId;

    /// Points to the input socket configuration, which will be represented by the CSocketConfiguration class.
    CSocketConfiguration inSocket;

    /// Points to the output socket configuration, which will be represented by the CSocketConfiguration class.
    CSocketConfiguration outSocket;

    /// Points to an external scripting file, to perform additional configuration actions. May be NULL.
    char *externalScipt;

    CChannelConfiguration() : deviceType( 0xFFFFFFFF ), channelId( 0xFFFFFFFF ), externalScipt( NULL )
    {
    }

    ~CChannelConfiguration()
    {
        if( NULL != externalScipt )
        {
            free( externalScipt );
            externalScipt = NULL;
        }
    }
};


/*----------------------------------------------------------*/
/*!
 * \brief Storage class for channel related informations. This class will be returned by
 *        the CVodXml class.
 */

/*----------------------------------------------------------*/
class CRouteTerminal
{
public:
    /// Determines the device type as specified in the configuration XML file and found in the group address configuration.
    uint32_t deviceType;

    /// instance number of the device found in the network
    uint32_t instance;

    /// Determines the used channel id, as specified in the configuration XML file.
    uint32_t channelId;
};




/*----------------------------------------------------------*/
/*!
 *  \brief Class to read XML for the Video On Demand use case.
 */

/*----------------------------------------------------------*/
class CVodXml : public CXml
{
private:
    /*----------------------------------------------------------*/
    /*! \brief Retrieves the control channel addresses used by the sever
     *
     *	\param rxEndpoint RX address will be written to this address (1 Byte)
     *	\param txEndpoint TX address will be written to this address (1 Byte)
     *  \return true, if successful
     */
    /*----------------------------------------------------------*/
    bool GetLocalInicConfigurations( uint8_t *rxEndpoint, uint8_t *txEndpoint );



    /*----------------------------------------------------------*/
    /*! \brief Retrieves the used physical interface used by the server for the MOST control channel.
     *
     *  \return Enumeration holding the physical interface.
     */
    /*----------------------------------------------------------*/
    SocketPort_t GetServerHardwareInterface();



    /*----------------------------------------------------------*/
    /*! \brief Retrieves the Port Message Protocol Version used by the server INIC.
     *
     *  \return 1 for INIC API V1, 2 for INIC API V2.
     */
    /*----------------------------------------------------------*/
    uint32_t GetServerDeviceApi();





    /*----------------------------------------------------------*/
    /*! \brief Retrieves the MOST parameters for the server attached INIC
     *
     *	\param isTimingMaster true will be written to this address, when INIC shall act as timing master. false, otherwise.
     *	\param asyncBandwidth The amount of bytes usable for asynchronous data will be written to this address.
     *  \return true, if successful
     */
    /*----------------------------------------------------------*/
    bool GetNetworkConfiguration( bool *isTimingMaster, uint32_t *asyncBandwidth );

public:
    /*----------------------------------------------------------*/
    /*! \brief Constructor of CVodXml.
     *
     *	\param szFile Path to configuration XML file.
     */
    /*----------------------------------------------------------*/
    CVodXml( const char *szFile );

    /*----------------------------------------------------------*/
    /*! \brief Retrieves all instances of the control channel addresses used by the sever
     *
     *	\param rxEndpoint RX address array will be written to this address (1 Byte)
     *	\param txEndpoint TX address array will be written to this address (1 Byte)
     *  \param serverNum The amount of found configurations will be written to this address.
     *  \note The user has to free the arrays rxEndpoint and txEndpoint after usage.
     *  \return true, if successful
     */
    /*----------------------------------------------------------*/
    bool GetLocalInicConfigurations( uint8_t *rxEndpoint[], uint8_t *txEndpoint[], uint32_t *apiVersion[],
        SocketPort_t *hwPort[], bool *isTimingMaster[], uint32_t *asyncBandwidth[], uint8_t *serverNum );


    bool GetMostParameters(bool *isTimingMaster, uint32_t *asyncBandwidth);


    /*----------------------------------------------------------*/
    /*! \brief Retrieves the Port Message Protocol Version used by the given device type.
     *
     *  \return 1 for INIC API V1, 2 for INIC API V2.
     */
    /*----------------------------------------------------------*/
    uint32_t GetDeviceApi( uint32_t deviceType );



    /*----------------------------------------------------------*/
    /*! \brief Retrieves the used MLB Port speed, if used.
     *
     *  \return The configured MLB port speed.
     */
    /*----------------------------------------------------------*/
    MlbPortSpeed_t GetDeviceMlbPortSpeed( uint32_t deviceType );




    /*----------------------------------------------------------*/
    /*! \brief Retrieves the MOST channel configurations for the given device type.
     *
     *	\param deviceType The device type to search for.
     *	\param allChannels A list with all channel configurations will be written into the given vector.
     *  \return true, if successful
     */
    /*----------------------------------------------------------*/
    bool GetChannelConfigurations( uint32_t deviceType, CSafeVector<CChannelConfiguration *> &allChannels );




    /*----------------------------------------------------------*/
    /*! \brief Retrieves the counter route terminals found in routes
     *
     *	\param routeTerminal - Route terminal, a counter terminal is searched for
     *  \return true, if successful
     */
    /*----------------------------------------------------------*/
    bool GetRouteTerminals( CRouteTerminal *routeTerminal, CSafeVector<CRouteTerminal *> &allRouteTerminals );



};

#endif //_VODXML_H_