/* * 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