/*
* 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 .
*
* You may also obtain this software under a propriety license from Microchip.
* Please contact Microchip for further information.
*
*/
/*----------------------------------------------------------*/
/*! \file
* \brief This file contains the CNetworkListner class.
*/
/*----------------------------------------------------------*/
#ifndef _NETWORK_H_
#define _NETWORK_H_
#include "SafeVector.h"
#include "Types.h"
#include "Thread.h"
#include "MacAddr.h"
#include "NetworkDevice.h"
#include "NetworkDeviceListener.h"
#include "VodXml.h"
/*----------------------------------------------------------*/
/*! \brief CNetworkListner class shall be derived from classes, which want them self to be registered as callback to the CNetwork class.
*/
/*----------------------------------------------------------*/
class CNetworkListner
{
public:
/*----------------------------------------------------------*/
/*! \brief This callback method is called whenever there is a new channel information available.
* \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
* \param mostInstance - The instance number of the MOST bus. If the server device has more then one physical MOST devices, each ring
* is identified by a unique id starting with 0 for the first MOST instance.
* \param available - true, if the network is fully usable. false, otherwise.
* \param maxPos - The amount of devices found in the network (inclusive master)
* \param packetBW - Amount of bytes reserved for Ethernet data (multiple with 48000 to get Byte/s)
*/
/*----------------------------------------------------------*/
virtual void OnNetworkState( uint8_t mostInstance, bool available, uint8_t maxPos, uint16_t packetBW );
/*----------------------------------------------------------*/
/*! \brief This callback method is called whenever there is a new channel information available.
* \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
* \param macAddr - The MAC address identifying the device unique.
* \param deviceId - The device identifier (group address) as specified in the XML file.
* \param devInst - The instance number of the device. Starting with 0 for the first device with deviceId.
* \param channelId - The channel identifier as specified in the XML file, given by "LoadConfig"-method of CNetwork class.
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring.
* \param dataType - The MOST data used by this channel.
* \param reservedBandwidth - The reserved MOST bandwidth in bytes for this channel.
* is identified by a unique id starting with 0 for the first MOST instance.
* \param isSourceDevice - true, if this device acts as source. false, if this device acts as sink.
* \param inSocketCreated - true, if the in-socket of the connection was created. false, there is no in-socket available at the moment.
* \param outSocketCreated - true, if the out-socket of the connection was created. false, there is no out-socket available at the moment.
* \param socketsConnected - true, if the in- and the out-socket are connected.
* \param splittedOffset - If this socket is a splitted / combined socket, this value holds the offset in byte. -1 if this is a normal socket.
* \param splittedMaxBandwidth - If this socket is a splitted / combined socket, this value holds the maximum bandwidth of all splitted sockets in byte. -1 if this is a normal socket.
* \param bufferSize - The amount of bytes reserved for this channel in Driver. If no buffers were allocated, this value is -1.
* \param packetsPerXactconst, This is USB specific. It describes how many sub-frames are concatenated into a single USB microframe.
* \param deviceName - The name of the Linux character device. May be NULL if the device is a remote device.
*/
/*----------------------------------------------------------*/
virtual void OnChannelAvailable( CMacAddr *macAddr, TDeviceId deviceId, uint8_t devInst, TChannelId channelId,
TMostInstace mostInstance, EPDataType_t dataType, TBlockwidth reservedBandwidth, bool isSourceDevice,
bool inSocketCreated, bool outSocketCreated, bool socketsConnected, int32_t bufferSize,
uint32_t mostConnectionLabel, int16_t splittedOffset, int16_t splittedMaxBandwidth,
uint16_t packetsPerXact, const char *deviceName );
/*----------------------------------------------------------*/
/*! \brief This callback method is called whenever a channel has become unavailable.
* \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
* \param macAddr - The MAC address identifying the device unique.
* \param channelId - The channel identifier as specified in the XML file, given by "LoadConfig"-method of CNetwork class.
* \param mostInstance - The instance number of the MOST bus. If the server device has more then one physical MOST devices, each ring
* is identified by a unique id starting with 0 for the first MOST instance.
*/
/*----------------------------------------------------------*/
virtual void OnChannelUnavailable( CMacAddr *macAddr, TChannelId channelId, uint8_t mostInstance );
/*----------------------------------------------------------*/
/*! \brief This callback method is called whenever a MOST control message was sent or received.
* \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
* \note The user may interpret the data and sent a corresponding MOST control message via CNetwork::SendMostControlMessage.
* \param devInst - The MOST ring instance, starting with 0 for the first MOST ring.
* \param sourceAddr - The MOST source address (may be not accurate)
* \param targetAddr - The MOST target address
* \param nFBlock - The MOST Function Block Identifier
* \param nInst - The MOST Function Block Instance Identifier
* \param nFunc - The MOST Function Block Function Identifier
* \param nPayloadLen - The amount of bytes stored in Payload
* \param Payload - The pointer to the payload byte array.
*/
/*----------------------------------------------------------*/
virtual void OnMostControlMessage( uint8_t devInst, uint32_t sourceAddr, uint32_t targetAddr, uint32_t nFBlock,
uint32_t nInst, uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload );
/*----------------------------------------------------------*/
/*! \brief Callback, when a Ring Break Diagnosis Result was received.
* \param devInst - The MOST ring instance, starting with 0 for the first MOST ring.
* \param nodeAddr - The device with this MOST node address raised this event.
* \praram result - The ring break diagnosis result
* \param position - Relative position to the ring break.
* \param status - Gives information about the activity state.
* \param id - The RBD identifier as configured in config string.
* \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
*/
/*----------------------------------------------------------*/
virtual void OnRingBreakDiagnosisResultV3( uint8_t devInst, uint16_t nodeAddress, uint8_t result,
uint8_t position, uint8_t status, uint16_t id );
};
/*----------------------------------------------------------*/
/*! \brief CNetwork represents the main controlling class, which opens and setup MOST connections.
*/
/*----------------------------------------------------------*/
class CNetwork : public CNetworkDeviceListener, public CThread
{
private:
bool allowNetworkRun;
char searchPath[256];
CSafeVector allListeners;
static CSafeVector allNetworkDevices;
CVodXml *vodXml;
sem_t vodXmlMutex;
uint32_t connectionBitMask;
bool promiscuous;
uint32_t retryCounter;
uint32_t retryExecTime;
CNetwork();
void DestroyAllResources( CNetworkDevice *device, uint16_t nodeAddress );
void CloseAllNetworkDevices();
void DestroyAllResources();
void FindNewNetworkDevices();
void TryToCreateRoute( uint32_t devInstance, bool mostIsTx, void *entry, void *terminal );
void TryToConnectSockets( uint32_t devInstance, uint16_t nodeAddr, uint32_t channelId );
void TryToCloseExistingMostConnection( void *inNode, uint32_t channelId, void *outNode, uint32_t outChannelId );
void RaiseAvailable( void *connection );
void RaiseUnavailable( void *connection );
CNetworkDevice *GetNetworkDevice( uint32_t devInstance );
CMacAddr *SetMacAddress( CNetworkDevice *device, uint32_t devInstance, uint16_t nodeAddress,
uint8_t inicApiVersion );
bool ConnectSourceToSink( void *mostTxNode, void *mostRxNode, uint32_t sourceChannelId, uint32_t sinkChannelId );
void RaiseUknownConnection( uint32_t devInstance, uint16_t nodeAddress, EPDataType_t dType );
void ShutdownMost( CNetworkDevice *device );
void ShutdownMostBecauseOfErrors( CNetworkDevice *device );
virtual void OnSync( void *source, bool isSynced );
virtual void OnNetworkState( void *source, bool mpValChanged, bool systemNotOk,
bool mostAvailable, uint8_t availableSubState, uint8_t availableTransition, uint16_t nodeAddress,
uint8_t nodePos, uint8_t maxPos, uint16_t packetBW );
virtual void OnNetworkStartupV3( void *source, bool success );
virtual void OnNetworkShutdownV3( void *source, bool success );
virtual void OnMostDeviceType( void *source, bool success, uint16_t nodeAddress, uint16_t deviceType );
virtual void OnCreateTsiSocketV1( void *source, bool success, uint16_t nodeAddr, V1TsiPortInstance_t tsiPortInst,
EPDataType_t epType, EPDirection_t epDir, uint16_t blockWidthTsi, uint16_t socketHandle, uint32_t tag );
virtual void OnCreateMlbSocketV1( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint16_t blockWidthMlb, uint8_t mlbChannelAddress, uint16_t socketHandle, uint32_t tag );
virtual void OnCreateMostSocketV1( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint16_t blockwidthMost, uint16_t connectionLabel, uint16_t socketHandle, uint32_t tag );
virtual void OnConnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t inSocketHandle,
uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag );
virtual void OnDestroySocketV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag );
virtual void OnDisconnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag );
virtual void OnCreateI2SSocketV1( void *source, bool success, uint16_t nodeAddr, EPDirection_t epDir,
uint16_t blockWidthI2S, V1I2SPin_t pin, uint16_t socketHandle, uint32_t tag );
virtual void OnCreateUsbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint8_t endPointAddress, uint16_t socketHandle, uint32_t tag );
virtual void OnCreateSplittedUsbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint8_t endPointAddress, uint16_t usbHandle, uint16_t splitterHandle, uint32_t tag );
virtual void OnCreateMlbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint16_t blockWidthMlb, uint8_t mlbChannelAddress, uint16_t socketHandle, uint32_t tag );
virtual void OnCreateSplittedMlbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint16_t blockWidthMlb, uint8_t mlbChannelAddress, uint16_t mlbSocketHandle,
uint16_t splitterHandle, uint32_t tag );
virtual void OnCreateI2SSocketV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
EPDirection_t epDir, uint16_t blockWidthI2S, V3I2SPin_t pin, uint16_t socketHandle, uint32_t tag );
virtual void OnCreateSplittedI2SSocketV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
EPDirection_t epDir, uint16_t blockWidthI2S, V3I2SPin_t pin, uint16_t i2sSocketHandle, uint16_t splitterHandle,
uint32_t tag );
virtual void OnCreateMostSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint16_t blockwidthMost, uint16_t connectionLabel, uint16_t socketHandle, uint32_t tag );
virtual void OnConnectSocketsV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
uint16_t inSocketHandle, uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag );
virtual void OnControlChannelReadEnd( void *source );
virtual void OnMostControlMessage( void *source, uint32_t sourceAddr, uint32_t targetAddr, uint32_t nFBlock,
uint32_t nInst, uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload );
virtual void OnRbdResultV3( void *source, uint16_t nodeAddress, uint8_t result, uint8_t position,
uint8_t status, uint16_t id );
virtual void OnMostMacAddress( void *source, bool success, uint16_t nodeAddress, uint8_t macAddress1,
uint8_t macAddress2, uint8_t macAddress3, uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6 );
virtual void OnConfigureI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
V3I2SPortOption_t option, V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag );
virtual void OnCreateI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
V3I2SPortSpeed_t clock, V3I2SAlignment_t align, uint32_t tag );
virtual void OnDeviceVersion( void *source, bool success, uint32_t sourceAddr,
uint32_t productId, uint32_t fwVersion, uint32_t buildVersion,
uint8_t hwVersion, uint16_t diagnosisId, uint32_t tag );
public:
/*----------------------------------------------------------*/
/*! \brief Destructor of CNetwork.
*/
/*----------------------------------------------------------*/
virtual ~CNetwork();
//Singleton pattern, there can only be one manager
/*----------------------------------------------------------*/
/*! \brief Gets the singleton instance of CNetwork (Only one object).
* \return Pointer to the singleton object.
*/
/*----------------------------------------------------------*/
static CNetwork *GetInstance( void );
/*----------------------------------------------------------*/
/*! \brief Registers the given CNetworkListener to this component.
* If there are events, all registered listeners will be called back.
* \note Multiple listerners are supported.
* \param listener- Class derivating CNetworkListener base class. This class will be called back on events.
*/
/*----------------------------------------------------------*/
void AddListener( CNetworkListner *listener );
/*----------------------------------------------------------*/
/*! \brief Deregisters the given CNetworkListener from this component.
* The given object will no longer be called back.
* \param listener- Class derivating CNetworkListener base class. This class will not be called after this method call.
*/
/*----------------------------------------------------------*/
void RemoveListener( CNetworkListner *listener );
/*----------------------------------------------------------*/
/*! \brief Enables or Disables the promiscuous mode on MEP channel. If enabled, tools like Wireshark will capture every packet.
* \param enabled - true, promiscuous mode. false, perfect match filter with multicast and broadcast enabled.
*/
/*----------------------------------------------------------*/
void SetPromiscuousMode( bool enabled );
/*----------------------------------------------------------*/
/*! \brief Loads a XML file holding information about connections and devices.
* \param szConfigXml - string holding only the filename to the XML file.
* \note This method tries to extract the search path from the given string. Therefor it must start with '/'.
* \note The given string will be modified by this method. Don't use it anymore after wise!
* \return true, if successful, false otherwise
*/
/*----------------------------------------------------------*/
bool LoadConfig( char *szConfigXml );
/*----------------------------------------------------------*/
/*! \brief Loads a XML file holding information about connections and devices.
* \param szConfigXml - string holding only the filename to the XML file.
* \param szSearchPath - string holding the path to all the XML files.
* \return true, if successful, false otherwise
*/
/*----------------------------------------------------------*/
bool LoadConfig( const char *szConfigXml, const char *szSearchPath );
/*----------------------------------------------------------*/
/*! \brief Checks if there are pending actions enqueued.
* \note This method blocks, until the result (true / false is reported by the subprocess).
* \return true, when there are pending actions in the queue. false, otherwise
*/
/*----------------------------------------------------------*/
bool ActionsPending();
/*----------------------------------------------------------*/
/*! \brief Connects a source to sink according to the configuration of the XML file, provided by LoadConfig method.
* \param SourceMacAddr - The MAC address of the source device, reported by the OnChannelAvailable callback method.
* \param SourceChannelId - The channel identifier of the source as specified in the XML file and reported by
* the OnChannelAvailable callback method.
* \param SinkMacAddr - The MAC address of the sink device, reported by the OnChannelAvailable callback method.
* \param SourceChannelId - The channel identifier of the sink as specified in the XML file and reported by
* the OnChannelAvailable callback method.
* \return true, if succesful. false, otherwise
*/
/*----------------------------------------------------------*/
bool ConnectSourceToSink( CMacAddr *SourceMacAddr, TChannelId SourceChannelId, CMacAddr *SinkMacAddr,
TChannelId SinkChannelId );
/*----------------------------------------------------------*/
/*! \brief Retrieves the amount of connected INIC nodes.
* \return The amount of local connected INIC nodes.
*/
/*----------------------------------------------------------*/
uint8_t GetAmountOfLocalNodes();
/*----------------------------------------------------------*/
/*! \brief Sends the given Control Message out to the given MOST ring
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
* \param targetAddr - The MOST target address (0x100, 0x401, etc..)
* \param nFBlock - The MOST Function Block Identifier
* \param nInst - The MOST Function Block Instance Identifier
* \param nFunc - The MOST Function Block Function Identifier
* \param nPayloadLen - The amount of bytes stored in Payload
* \param Payload - The pointer to the payload byte array.
*/
/*----------------------------------------------------------*/
bool SendMostControlMessage( TMostInstace mostInstance, uint32_t targetAddr, uint32_t nFBlock, uint32_t nInst,
uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload );
/*----------------------------------------------------------*/
/*! \brief Sends the given Control Message out to the given MOST ring
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
* \param deviceId - The device identifier (group address) as specified in the XML file
* \param devInst - The instance number of the device. Starting with 0 for the first device with deviceId
* \param nFBlock - The MOST Function Block Identifier
* \param nInst - The MOST Function Block Instance Identifier
* \param nFunc - The MOST Function Block Function Identifier
* \param nPayloadLen - The amount of bytes stored in Payload
* \param Payload - The pointer to the payload byte array.
*/
/*----------------------------------------------------------*/
bool SendMostControlMessage( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst, uint32_t nFBlock,
uint32_t nInst, uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload );
/*----------------------------------------------------------*/
/*! \brief Executes a given XML script by it's filename and MOST target address
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
* \param targetAddr - The MOST target address (0x100, 0x401, etc..)
* \param szFile - Path to the XML file (zero terminated string)
*/
/*----------------------------------------------------------*/
bool ExecuteXmlScriptFromFile( TMostInstace mostInstance, uint32_t targetAddr, const char *szFile );
/*----------------------------------------------------------*/
/*! \brief Executes a given XML script by it's filename, device identifier and device instance
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
* \param deviceId - The device identifier (group address) as specified in the XML file
* \param devInst - The instance number of the device. Starting with 0 for the first device with deviceId
* \param szFile - Path to the XML file (zero terminated string)
*/
/*----------------------------------------------------------*/
bool ExecuteXmlScriptFromFile( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst,
const char *szFile );
/*----------------------------------------------------------*/
/*! \brief Executes a given XML script directly by it's content stored in the memory and MOST target address
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
* \param targetAddr - The MOST target address (0x100, 0x401, etc..)
* \param szBuffer - The Buffer containing the XML script
* \param nBufferLen - The length of the XML script stored in szBuffer
*/
/*----------------------------------------------------------*/
bool ExecuteXmlScriptFromMemory( TMostInstace mostInstance, uint32_t targetAddr, const char *szBuffer,
uint32_t nBufferLen );
/*----------------------------------------------------------*/
/*! \brief Executes a given XML script by it's filename, device identifier and device instance
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
* \param targetAddr - The MOST target address (0x100, 0x401, etc..)
* \param szBuffer - The Buffer containing the XML script
* \param nBufferLen - The length of the XML script stored in szBuffer
*/
/*----------------------------------------------------------*/
bool ExecuteXmlScriptFromMemory( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst,
const char *szBuffer, uint32_t nBufferLen );
/*!
* \brief Storage class for channel related informations. This class will be returned by
* the CVodXml class.
*/
typedef struct
{
/// 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;
} Route_t;
/*----------------------------------------------------------*/
/*! \brief Sends the given Control Message out to the given MOST ring.
* \param pInRoute - Pointer to the route to search the counter part of.
* \param pOutRouteArray - Pointer to pointer, which then the result array will be stored, maybe NULL!
* \return The array length of pOutRouteArray, maybe 0!
* \note The pOutRouteArray must be freed by the user after usage!
*/
/*----------------------------------------------------------*/
uint32_t GetCounterPartOfRoute( const Route_t *pInRoute, Route_t **pOutRouteArray );
/*----------------------------------------------------------*/
/*! \brief Retrieves the stored result of the Ring Break Diagnosis
* \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
* \param targetAddr - The MOST target address (0x100, 0x401, etc..)
* \return true, if successful, false otherwise
*/
/*----------------------------------------------------------*/
bool GetRingBreakDiagnosisResult( TMostInstace mostInstance, uint32_t targetAddr );
/*----------------------------------------------------------*/
/*! \brief Enables or disables all MOST rings.
* \note This is thought for debug reasons only. Normally this method must not be called.
* \param enabled - TRUE, all MOST rings will start up. FALSE, all MOST rings will shutdown.
*/
/*----------------------------------------------------------*/
void EnableMost(bool enabled);
/*----------------------------------------------------------*/
/*! \brief Function of background thread.
* \note Never call this method. It is used by internal threads.
*/
/*----------------------------------------------------------*/
void Run();
};
#endif