summaryrefslogtreecommitdiffstats
path: root/Src/Network/NetworkDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Network/NetworkDevice.cpp')
-rw-r--r--Src/Network/NetworkDevice.cpp903
1 files changed, 903 insertions, 0 deletions
diff --git a/Src/Network/NetworkDevice.cpp b/Src/Network/NetworkDevice.cpp
new file mode 100644
index 0000000..5308215
--- /dev/null
+++ b/Src/Network/NetworkDevice.cpp
@@ -0,0 +1,903 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include "NetworkDevice.h"
+#include "DriverConfiguration.h"
+#include "Board.h"
+#include "ScriptXml.h"
+#include "IndustrialStack_ApiV1.h"
+#include "IndustrialStack_ApiV3.h"
+#include "IndustrialStack_ApiGeneric.h"
+
+CNetworkDevice::CNetworkDevice( uint8_t index, uint8_t api, bool master, uint32_t asyncBW, bool promiscuousMode ) :
+CThread( "CNetworkDevice", false ), promiscuous( promiscuousMode ), netState( NetworkState_Unknown ),
+ pInic( NULL ), pScriptMemoryArea( NULL ), isRunning( false ),
+ isActionPending( false ), deviceIndex( index ), deviceApi( api ),
+ isTimingMaster( master ), asyncBandwidth( asyncBW ),
+ controlEndpointRxHandle( -1 ), controlEndpointTxHandle( -1 ),
+ startV3autoForced( 0xFFFF ), startV3packetBW( 0xFFFF )
+{
+ responseToWaitFor[0] = '\0';
+ deviceNameControlRx[0] = '\0';
+ deviceNameControlTx[0] = '\0';
+
+ sem_init( &methodMutex, 0, 0 ); //Mutex, initialized to 0 => sem_wait will block
+}
+
+CNetworkDevice::~CNetworkDevice()
+{
+ Stop();
+ CloseMostControlChannel();
+ if (NULL != iStack)
+ {
+ delete iStack;
+ iStack = NULL;
+ }
+ if (NULL != v1Events)
+ {
+ delete v1Events;
+ v1Events = NULL;
+ }
+ if (NULL != v3Events)
+ {
+ delete v3Events;
+ v3Events = NULL;
+ }
+}
+
+bool CNetworkDevice::OpenDevice( const char *systemNameControlRx, const char *systemNameControlTx,
+ const char *linkNameControlRx, const char *linkNameControlTx )
+{
+ ConsolePrintf( PRIO_LOW, "SYS RX:%s\nSYS TX:%s\nLINK RX:%s\nLINK TX:%s\n", systemNameControlRx,
+ systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ CloseMostChannel( systemNameControlRx );
+ CloseMostChannel( systemNameControlTx );
+
+ bool success = ConfigureMostChannel( systemNameControlRx, EP_Control, EPDIR_OUT, 32, 128 );
+
+ if( success )
+ {
+ success = ConfigureMostChannel( systemNameControlTx, EP_Control, EPDIR_IN, 32, 128 );
+ }
+
+ if( success )
+ {
+ success = LinkToCharacterDevice( linkNameControlRx, deviceNameControlRx );
+ }
+
+ if( success )
+ {
+ success = LinkToCharacterDevice( linkNameControlTx, deviceNameControlTx );
+ }
+
+ if( success )
+ {
+ if( OpenMostControlChannel() )
+ {
+ isRunning = true;
+ Start();
+ }
+ else
+ {
+ ConsolePrintf( PRIO_ERROR, RED"MOST control channel startup failed"RESETCOLOR"\n" );
+ }
+
+ }
+ else
+ {
+ ConsolePrintf(
+ PRIO_ERROR, RED"NetworkDevice: Open device aborted, because of channel configuration issues"RESETCOLOR"\n" );
+ }
+ return success;
+}
+
+bool CNetworkDevice::OpenUsb( uint8_t controlRxEndpointAddress, uint8_t controlTxEndpointAddress )
+{
+ char systemNameControlRx[64];
+ char systemNameControlTx[64];
+ char linkNameControlRx[64];
+ char linkNameControlTx[64];
+ bool success = GetUsbDeviceNames( deviceIndex, controlRxEndpointAddress,
+ deviceNameControlRx, sizeof( deviceNameControlRx ), systemNameControlRx, sizeof( systemNameControlRx ),
+ linkNameControlRx, sizeof( linkNameControlRx ) );
+
+ if( success )
+ success = GetUsbDeviceNames( deviceIndex, controlTxEndpointAddress,
+ deviceNameControlTx, sizeof( deviceNameControlTx ), systemNameControlTx, sizeof( systemNameControlTx ),
+ linkNameControlTx, sizeof( linkNameControlTx ) );
+
+ if( success )
+ success = OpenDevice( systemNameControlRx, systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ if( ! success )
+ ConsolePrintf( PRIO_ERROR, RED"NetworkDevice: Failed to open USB device"RESETCOLOR"\n" );
+
+ return success;
+}
+
+bool CNetworkDevice::OpenMlb( uint8_t controlRxChannelAddress, uint8_t controlTxChannelAddress )
+{
+ char systemNameControlRx[64];
+ char systemNameControlTx[64];
+ char linkNameControlRx[64];
+ char linkNameControlTx[64];
+ bool success = GetMlbDeviceNames( deviceIndex, controlRxChannelAddress,
+ deviceNameControlRx, sizeof( deviceNameControlRx ), systemNameControlRx, sizeof( systemNameControlRx ),
+ linkNameControlRx, sizeof( linkNameControlRx ) );
+
+ if( success )
+ success = GetMlbDeviceNames( deviceIndex, controlTxChannelAddress,
+ deviceNameControlTx, sizeof( deviceNameControlTx ), systemNameControlTx, sizeof( systemNameControlTx ),
+ linkNameControlTx, sizeof( linkNameControlTx ) );
+
+ if( success )
+ success = OpenDevice( systemNameControlRx, systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ if( ! success )
+ ConsolePrintf( PRIO_ERROR, RED"NetworkDevice: Failed to open MLB device"RESETCOLOR"\n" );
+
+ return success;
+}
+
+bool CNetworkDevice::OpenI2C()
+{
+ char systemNameControlRx[64];
+ char systemNameControlTx[64];
+ char linkNameControlRx[64];
+ char linkNameControlTx[64];
+ bool success = GetI2CDeviceNames( deviceIndex, false, deviceNameControlRx, sizeof( deviceNameControlRx ),
+ systemNameControlRx, sizeof( systemNameControlRx ), linkNameControlRx, sizeof( linkNameControlRx ) );
+
+ if( success )
+ success = GetI2CDeviceNames( deviceIndex, true, deviceNameControlTx, sizeof( deviceNameControlTx ),
+ systemNameControlTx, sizeof( systemNameControlTx ), linkNameControlTx, sizeof( linkNameControlTx ) );
+
+ if( success )
+ success = OpenDevice( systemNameControlRx, systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ if( ! success )
+ ConsolePrintf( PRIO_ERROR, RED"NetworkDevice: Failed to open I2C device"RESETCOLOR"\n" );
+
+ return success;
+}
+
+void CNetworkDevice::Close()
+{
+ int32_t timeoutVal = 10; //10 Seconds
+ while( timeoutVal-- > 0 )
+ {
+ if( iStack->ElementsPending() )
+ {
+ ConsolePrintf( PRIO_MEDIUM, "NetworkDevice: Closing delayed, Actions pending..\n" );
+ usleep( 1000000 );
+ }
+ else
+ {
+ break;
+ }
+ }
+ sem_post( &methodMutex );
+ isRunning = false;
+ Stop();
+ for( uint32_t timeout = 0; timeout < 100; timeout++ )
+ {
+ if( !IsThreadRunning() )
+ break;
+ usleep( 10000 );
+ }
+ ConsolePrintf( PRIO_LOW, "NetworkDevice: Closed..\n" );
+}
+
+uint8_t CNetworkDevice::GetDeviceApi()
+{
+ return deviceApi;
+}
+
+NetworkState_t CNetworkDevice::GetNetState()
+{
+ return netState;
+}
+
+void CNetworkDevice::SetNetstate( NetworkState_t newState )
+{
+ netState = newState;
+}
+
+ void CNetworkDevice::SetTimingMaster(bool tm)
+ {
+ isTimingMaster = tm;
+ }
+
+bool CNetworkDevice::IsTimingMaster()
+{
+ return isTimingMaster;
+}
+
+void CNetworkDevice::SetAsyncBandwidth(uint32_t bw)
+{
+ asyncBandwidth = bw;
+}
+
+uint32_t CNetworkDevice::GetAsyncBandwidth()
+{
+ return asyncBandwidth;
+}
+
+bool CNetworkDevice::ActionsPending()
+{
+ if( NULL == iStack || !isRunning )
+ return true;
+ return iStack->ElementsPending();
+}
+
+void CNetworkDevice::ClearAllPendingActions()
+{
+ if( NULL == iStack )
+ return;
+ iStack->ClearAllElements();
+}
+
+void CNetworkDevice::AddListener( CNetworkDeviceListener *listener )
+{
+ allListeners.PushBack( listener );
+}
+
+uint32_t CNetworkDevice::GetAmountOfListners()
+{
+ return allListeners.Size();
+}
+
+CNetworkDeviceListener *CNetworkDevice::GetListener( uint32_t instance )
+{
+ return allListeners[instance];
+}
+
+uint8_t CNetworkDevice::GetDeviceIndex()
+{
+ return deviceIndex;
+}
+
+void CNetworkDevice::ScriptPause( uint32_t timeInMillis )
+{
+ CISWaitElement *waitElement = new CISWaitElement();
+ waitElement->SetTimeout(timeInMillis);
+ iStack->EnqueueElement(0x1, waitElement);
+ waitElement->RemoveReference();
+}
+
+void CNetworkDevice::ExecuteMcmScript( uint16_t nodeAddress, CSciptXml *scriptXml )
+{
+ if( NULL == scriptXml )
+ {
+ ConsolePrintf(
+ PRIO_ERROR, RED"ExecuteMcmScript failed to retrieve scripts from XML file"RESETCOLOR"\n" );
+ return;
+ }
+ CSafeVector<CScript *> allScripts;
+ if( scriptXml->GetScripts( allScripts ) )
+ {
+ for (uint32_t i = 0; i < allScripts.Size(); i++ )
+ {
+ CScript *script = allScripts[i];
+ if( NULL == script )
+ continue;
+ switch( script->scriptType )
+ {
+ case SCRIPT_MCM_SEND:
+ {
+ CGeneric_SendMostMessage *a = new CGeneric_SendMostMessage(
+ script->payload, script->payloadLength, nodeAddress,
+ script->fblockId, 0, script->functionId, script->opTypeRequest,
+ script->opTypeResponse);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+ break;
+ }
+ case SCRIPT_PAUSE:
+ {
+ CISWaitElement *waitElement = new CISWaitElement();
+ waitElement->SetTimeout(script->pauseInMillis);
+ iStack->EnqueueElement(nodeAddress, waitElement);
+ waitElement->RemoveReference();
+ break;
+ }
+ default:
+ ConsolePrintf( PRIO_ERROR,
+ YELLOW"ExecuteMcmScript ignoring unknown script type:%d"RESETCOLOR"\n",
+ script->scriptType );
+ break;
+ }
+ }
+ }
+ allScripts.RemoveAll(true);
+}
+
+void CNetworkDevice::ExecuteMcmScript( uint16_t nodeAddress, const char *pPathToScriptXml )
+{
+ if( NULL == pPathToScriptXml )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"ExecuteMcmScript (from file) was called with invalid parameter"RESETCOLOR"\n" );
+ return;
+ }
+ ConsolePrintf( PRIO_MEDIUM, "##### Executing MCM script from file: Address:%X '%s'\n", nodeAddress,
+ pPathToScriptXml );
+ CSciptXml *scriptXml = new CSciptXml( pPathToScriptXml );
+ ExecuteMcmScript( nodeAddress, scriptXml );
+}
+
+void CNetworkDevice::ExecuteMcmScript( uint16_t nodeAddress, const char *pStringBuffer, uint32_t bufferLength )
+{
+ if( NULL == pStringBuffer || 0 == bufferLength )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"ExecuteMcmScript (from memory) was called with invalid parameter"RESETCOLOR"\n" );
+ return;
+ }
+ ConsolePrintf( PRIO_MEDIUM, "##### Executing MCM script from memory: Address:%X buffer-len:\n", nodeAddress,
+ bufferLength );
+ CSciptXml *scriptXml = new CSciptXml( pStringBuffer, bufferLength );
+ ExecuteMcmScript( nodeAddress, scriptXml );
+}
+
+void CNetworkDevice::ToggleNotOk()
+{
+ CGeneric_SendConfigOk *a = new CGeneric_SendConfigOk(false);
+ iStack->EnqueueElement(0x3C8, a);
+ a->RemoveReference();
+
+ CGeneric_SendConfigOk *b = new CGeneric_SendConfigOk(true);
+ iStack->EnqueueElement(0x3C8, b);
+ b->RemoveReference();
+}
+
+void CNetworkDevice::GetMacAddress( uint16_t nodeAddress )
+{
+ CGeneric_GetMacAddress *a = new CGeneric_GetMacAddress(nodeAddress);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::GetGroupAddresses( uint8_t maxNodePos )
+{
+ for( uint32_t i = 0x400; maxNodePos != 0xFF && i < 0x400 + ( uint32_t )maxNodePos; i++ )
+ {
+ uint16_t n = ( i == 0x400 ? 1 : i );
+ CGeneric_GetGroupAddress *a = new CGeneric_GetGroupAddress(n);
+ iStack->EnqueueElement(n, a);
+ a->RemoveReference();
+ }
+}
+
+void CNetworkDevice::SetMostMacAddressV1( uint16_t nodeAddress, uint8_t macAddress1, uint8_t macAddress2,
+ uint8_t macAddress3, uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6, bool persistent )
+{
+ CV1_ChangeEUI48 *a = new CV1_ChangeEUI48(this, nodeAddress, macAddress1, macAddress2,
+ macAddress3, macAddress4, macAddress5, macAddress6, persistent);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::StartMostV1( bool isTimingMaster, uint16_t packetBandWidth )
+{
+ CV1_NetworkStartup *a = new CV1_NetworkStartup(this, isTimingMaster, packetBandWidth);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkShutdownV1()
+{
+ CISWaitForPendingElements *w = new CISWaitForPendingElements(0x1);
+ iStack->EnqueueElement(0x1, w);
+ w->RemoveReference();
+
+ CV1_NetworkShutdown *a = new CV1_NetworkShutdown(this);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenTsiV1( uint16_t nodeAddress, V1TsiPortInstance_t tsiPortId, V1TsiPortMode tsiPortMode )
+{
+ if (V1TsiPortInstanceNotSet == tsiPortId || V1TsiPortModeNotSet == tsiPortMode)
+ return;
+ CV1_TsiPortCreate *a = new CV1_TsiPortCreate(this, nodeAddress, tsiPortId, tsiPortMode);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateTsiSocketV1( uint16_t nodeAddress, V1TsiPortInstance_t portInst,
+ EPDataType_t epType, EPDirection_t epDir,uint16_t blockWidthTsi, uint32_t tag )
+{
+ CV1_TsiSocketCreate *a = new CV1_TsiSocketCreate(this, nodeAddress, portInst,
+ epType, epDir, blockWidthTsi, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenMlbV1( uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed )
+{
+ if( MlbSpeedNotSet == mlbSpeed )
+ return;
+ CV1_MlbPortCreate *a = new CV1_MlbPortCreate(this, nodeAddress, mlbSpeed);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMlbSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t mlbChannelAddress, uint16_t blockWidthMlb, uint32_t tag )
+{
+ CV1_MlbSocketCreate *a = new CV1_MlbSocketCreate(this, nodeAddress, epType, epDir,
+ mlbChannelAddress, blockWidthMlb, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedMlbSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t mlbChannelAddress, uint16_t blockWidthMlb, uint16_t splittedOffset, uint16_t blockWidthCombined,
+ uint32_t tag )
+{
+ CV1_SplittedMlbSocketCreate *a = new CV1_SplittedMlbSocketCreate(this, nodeAddress,
+ epType, epDir, mlbChannelAddress, blockWidthMlb, splittedOffset, blockWidthCombined, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMostSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t connectionLabel, uint16_t blockWidthMost, uint32_t tag )
+{
+ CV1_MostSocketCreate *a = new CV1_MostSocketCreate(this, nodeAddress,
+ epType, epDir, connectionLabel, blockWidthMost, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ConnectSocketsV1( uint16_t nodeAddress, uint8_t inHandle, uint8_t outHandle, uint32_t tag )
+{
+ CV1_ConnectSockets *a = new CV1_ConnectSockets(this, nodeAddress,
+ inHandle, outHandle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::DestroySocketV1( uint16_t nodeAddress, uint8_t handle, uint32_t tag )
+{
+ CV1_DestroySocket *a = new CV1_DestroySocket(this, nodeAddress, handle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::DisconnectSocketsV1( uint16_t nodeAddress, uint8_t handle, uint32_t tag )
+{
+ CV1_DisconnectSockets *a = new CV1_DisconnectSockets(this, nodeAddress, handle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenStreamPortV1( uint16_t nodeAddress, V1I2SPortClkDriveMode_t portMode,
+ V1I2SStreamingPortMode_t streamPortMode, V1I2SStreamingDataFormat_t format, uint32_t tag )
+{
+ CV1_StreamPortOpen *a = new CV1_StreamPortOpen(this, nodeAddress, portMode, streamPortMode, format, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateStreamSocketV1( uint16_t nodeAddress, EPDirection_t epDir, uint16_t blockWidthI2S,
+ V1I2SPin_t pin, uint32_t tag )
+{
+ CV1_StreamSocketCreate *a = new CV1_StreamSocketCreate(this, nodeAddress, epDir, blockWidthI2S, pin, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedStreamSocketV1( uint16_t nodeAddress, EPDirection_t epDir, uint16_t blockWidthI2S,
+ uint16_t splittedOffset, uint16_t blockWidthCombined, V1I2SPin_t pin, uint32_t tag )
+{
+ CV1_SplittedStreamSocketCreate *a = new CV1_SplittedStreamSocketCreate(this,
+ nodeAddress, epDir, blockWidthI2S, splittedOffset, blockWidthCombined, pin, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::AttachV3()
+{
+ CV3_DeviceAttach *a = new CV3_DeviceAttach();
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::InicUnsychronizeV3()
+{
+ CISWaitForPendingElements *w = new CISWaitForPendingElements(0x1);
+ iStack->EnqueueElement(0x1, w);
+ w->RemoveReference();
+
+ CV3_Unsynchronize *a = new CV3_Unsynchronize();
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::DeviceSyncV3( uint16_t nodeAddress, bool sync )
+{
+ CV3_DeviceSync *a = new CV3_DeviceSync(nodeAddress, sync);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkStartupV3( uint16_t autoForcedNotAvailable, uint16_t packetBW )
+{
+ startV3autoForced = autoForcedNotAvailable;
+ startV3packetBW = packetBW;
+ CV3_NetworkStartup *a = new CV3_NetworkStartup(this, autoForcedNotAvailable, packetBW);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkStartupV3()
+{
+ if( 0xFFFF == startV3packetBW )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Repeated MostNetworkStartupV3 was called"\
+ " without calling the overloaded MostNetworkStartupV3 with parameters"\
+ RESETCOLOR"\n" );
+ return;
+ }
+ CV3_NetworkStartup *a = new CV3_NetworkStartup(this, startV3autoForced, startV3packetBW);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkShutdownV3()
+{
+ CISWaitForPendingElements *w = new CISWaitForPendingElements(0x1);
+ iStack->EnqueueElement(0x1, w);
+ w->RemoveReference();
+
+ CV3_NetworkShutdown *a = new CV3_NetworkShutdown(this);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::SetMostMacAddressV3( uint16_t nodeAddress, uint8_t macAddress1, uint8_t macAddress2,
+ uint8_t macAddress3, uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6 )
+{
+ CV3_MostNetworkConfiguration *a = new CV3_MostNetworkConfiguration(this, nodeAddress, macAddress1, macAddress2,
+ macAddress3, macAddress4, macAddress5, macAddress6, promiscuous);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenMlbV3( uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed )
+{
+ if( MlbSpeedNotSet == mlbSpeed )
+ return;
+ CV3_MlbPortCreate *a = new CV3_MlbPortCreate(this, nodeAddress, mlbSpeed);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateUsbSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint8_t endPointAddress, uint16_t packetsPerFrame, uint32_t tag )
+{
+ CV3_UsbSocketCreate *a = new CV3_UsbSocketCreate(this, nodeAddress, epType,
+ epDir, endPointAddress, packetsPerFrame, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedUsbSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint8_t endPointAddress, uint16_t packetsPerFrame, uint16_t bytesPerPacket, uint32_t tag )
+{
+ CV3_SplittedUsbSocketCreate *a = new CV3_SplittedUsbSocketCreate(this, nodeAddress,
+ epType, epDir, endPointAddress, packetsPerFrame, bytesPerPacket, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMlbSocketV3( uint16_t nodeAddress, uint16_t mlbPortHandle, EPDataType_t epType,
+ EPDirection_t epDir, uint16_t mlbChannelAddress, uint16_t blockwidthMlb, uint32_t tag )
+{
+ CV3_MlbSocketCreate *a = new CV3_MlbSocketCreate(this, nodeAddress, mlbPortHandle,
+ epType, epDir, mlbChannelAddress, blockwidthMlb, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedMlbSocketV3( uint16_t nodeAddress, uint16_t mlbPortHandle, EPDataType_t epType,
+ EPDirection_t epDir, uint16_t mlbChannelAddress, uint16_t blockwidthMlb, uint16_t bytesPerPacket, uint32_t tag )
+{
+ CV3_SplittedMlbSocketCreate *a = new CV3_SplittedMlbSocketCreate(this, nodeAddress,
+ mlbPortHandle, epType, epDir, mlbChannelAddress, blockwidthMlb, bytesPerPacket, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMostSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t connectionLabel, uint16_t blockwidthMost, uint32_t tag )
+{
+ CV3_MostSocketCreate *a = new CV3_MostSocketCreate(this, nodeAddress, epType,
+ epDir, connectionLabel, blockwidthMost, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ConnectSocketsV3( uint16_t nodeAddress, EPDataType_t epType, uint16_t inHandle,
+ uint16_t outHandle, uint16_t offset, uint32_t tag )
+{
+ CV3_ConnectSockets *a = new CV3_ConnectSockets(this, nodeAddress, epType,
+ inHandle, outHandle, offset, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ResourceDestroyV3( uint16_t nodeAddress, uint8_t amountOfHandles, const uint16_t *pHandle,
+ uint32_t tag )
+{
+ CV3_ResourceDestroy *a = new CV3_ResourceDestroy(this, nodeAddress,
+ amountOfHandles, pHandle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ConfigureStreamPortV3( uint16_t nodeAddress, uint8_t portInstance, V3I2SPortOption_t option,
+ V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag )
+{
+ CV3_StreamPortConfig *a = new CV3_StreamPortConfig(this, nodeAddress,
+ portInstance, option, mode, delay, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateStreamPortV3( uint16_t nodeAddress, uint8_t portInstance, V3I2SPortSpeed_t clock,
+ V3I2SAlignment_t align, uint32_t tag )
+{
+ CV3_StreamPortCreate *a = new CV3_StreamPortCreate(this, nodeAddress,
+ portInstance, clock, align, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateStreamSocketV3( uint16_t nodeAddress, uint8_t portInstance, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V3I2SPin_t pin, uint32_t tag )
+{
+ CV3_StreamSocketCreate *a = new CV3_StreamSocketCreate(this, nodeAddress,
+ portInstance, epDir, blockWidthI2S, pin, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedStreamSocketV3( uint16_t nodeAddress, uint8_t portInstance, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V3I2SPin_t pin, uint16_t bytesPerPacket, uint32_t tag )
+{
+ CV3_SplittedStreamSocketCreate *a = new CV3_SplittedStreamSocketCreate(this, nodeAddress,
+ portInstance, epDir, blockWidthI2S, pin, bytesPerPacket, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::GetRingBreakResultV3( uint16_t nodeAddress, uint32_t tag )
+{
+ CV3_GetRbdResult *a = new CV3_GetRbdResult(nodeAddress);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+bool CNetworkDevice::OpenMostControlChannel( void )
+{
+ bool success = false;
+ for (uint8_t i = 0; !success && i < 10; i++)
+ {
+ if (-1 == controlEndpointRxHandle)
+ controlEndpointRxHandle = open( deviceNameControlRx, O_RDONLY );
+ if (-1 == controlEndpointTxHandle)
+ controlEndpointTxHandle = open( deviceNameControlTx, O_WRONLY );
+ success = (-1 != controlEndpointRxHandle && -1 != controlEndpointTxHandle);
+ if (!success)
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Opened file handles failed TX:%d RX:%d, retrying.."RESETCOLOR"\n", controlEndpointTxHandle, controlEndpointRxHandle);
+ usleep(1000000);
+ }
+ }
+
+ if( success )
+ {
+ iStack = new CIndustrialStack(deviceApi, controlEndpointRxHandle, controlEndpointTxHandle);
+ v1Events = new CV1_OnMostRx(this);
+ v3Events = new CV3_OnMostRx(this);
+ iStack->AddInternalEventListener(this);
+ iStack->AddInternalEventListener(v1Events);
+ iStack->AddInternalEventListener(v3Events);
+ }
+ else
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Failure while opening MOST control channel" \
+ " ('%s' or '%s'), error='%s'"RESETCOLOR"\n"
+ , deviceNameControlRx, deviceNameControlTx, GetErrnoString() );
+ }
+ return success;
+}
+
+void CNetworkDevice::Run( void )
+{
+ iStack->ServiceStack(GetTickCount());
+ usleep( 1000 );
+}
+
+void CNetworkDevice::CloseMostControlChannel( void )
+{
+ close( controlEndpointTxHandle );
+ close( controlEndpointRxHandle );
+ if (NULL != iStack)
+ {
+ delete iStack;
+ iStack = NULL;
+ }
+}
+
+void CNetworkDevice::WaitForIpcResponse( const char *responseMessage )
+{
+ if( isRunning )
+ {
+ strncpy( ( char * )responseToWaitFor, responseMessage, sizeof( responseToWaitFor ) );
+ sem_wait( &methodMutex );
+ responseToWaitFor[0] = '\0';
+ }
+}
+
+bool CNetworkDevice::ConfigureUsbEndpoint( AimType_t aimType, uint8_t endpointAddress, EPDataType_t epType,
+ EPDirection_t epDir, char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize,
+ uint32_t subbufferSize, uint32_t packetsPerTransaction )
+{
+ char systemName[64];
+ char linkName[64];
+ bool success = GetUsbDeviceNames( deviceIndex, endpointAddress, deviceName, deviceNameBufLen,
+ systemName, sizeof( systemName ), linkName, sizeof( linkName ) );
+ if( !success )
+ return success;
+ CloseMostChannel( systemName );
+ switch( epType )
+ {
+ case EP_Synchron:
+ success = ConfigureSyncChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ break;
+ case EP_Isochron:
+ success = ConfigureIsocChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ break;
+ default:
+ break;
+ }
+ if( success )
+ {
+ switch( aimType )
+ {
+ case AIM_AUDIO:
+ success = LinkToAudioDevice( linkName, subbufferSize );
+ break;
+ case AIM_V4L:
+ success = LinkToVideoForLinuxDevice( linkName );
+ break;
+ case AIM_CDEV:
+ default:
+ success = LinkToCharacterDevice( linkName, deviceName );
+ break;
+ }
+ }
+ return success;
+}
+
+bool CNetworkDevice::ConfigureUsbEndpoint( uint8_t endpointAddress, EPDataType_t epType, EPDirection_t epDir,
+ char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize )
+{
+ return ConfigureUsbEndpoint( AIM_CDEV, endpointAddress, epType, epDir, deviceName, deviceNameBufLen,
+ amountOfBuffers, bufferSize, 0, 0 );
+}
+
+bool CNetworkDevice::ConfigureMlbChannel( AimType_t aimType, uint8_t mlbChannelAddress, EPDataType_t epType,
+ EPDirection_t epDir, char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize,
+ uint32_t subbufferSize, uint32_t packetsPerTransaction )
+{
+ char systemName[64];
+ char linkName[64];
+ bool success = GetMlbDeviceNames( deviceIndex, mlbChannelAddress, deviceName, deviceNameBufLen,
+ systemName, sizeof( systemName ), linkName, sizeof( linkName ) );
+ if( !success )
+ return false;
+ CloseMostChannel( systemName );
+ switch( epType )
+ {
+ case EP_Synchron:
+ success = ConfigureSyncChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ if( success )
+ {
+ switch( aimType )
+ {
+ case AIM_AUDIO:
+ success = LinkToAudioDevice( linkName, subbufferSize );
+ break;
+ case AIM_CDEV:
+ default:
+ success = LinkToCharacterDevice( linkName, deviceName );
+ break;
+ }
+ }
+ break;
+ case EP_Isochron:
+ success = ConfigureIsocChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ if( success )
+ success = LinkToCharacterDevice( linkName, deviceName );
+ break;
+ default:
+ break;
+ }
+ return success;
+}
+
+bool CNetworkDevice::ConfigureMlbChannel( uint8_t mlbChannelAddress, EPDataType_t epType, EPDirection_t epDir,
+ char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize )
+{
+ return ConfigureMlbChannel( AIM_CDEV, mlbChannelAddress, epType, epDir, deviceName, deviceNameBufLen,
+ amountOfBuffers, bufferSize, 0, 0 );
+}
+
+bool CNetworkDevice::SendMostControlMessage( uint8_t devInst, uint32_t targetAddr, uint32_t nFBlock, uint32_t nInst,
+ uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload )
+{
+ CGeneric_SendMostMessage *a = new CGeneric_SendMostMessage(Payload,
+ nPayloadLen, targetAddr, nFBlock, nInst, nFunc, nOpType, 0xFF);
+ iStack->EnqueueElement(targetAddr, a);
+ a->RemoveReference();
+ return true;
+}
+
+void CNetworkDevice::GetDeviceVersion( uint16_t nodeAddress )
+{
+ CV3_DeviceVersion *a = new CV3_DeviceVersion(this, nodeAddress, 0);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+ISReturn_t CNetworkDevice::OnMostMessage(CIndustrialStack *iStack, CISMostMsg *r)
+{
+ if (NULL == r)
+ return ISReturn_NoChange;
+ for (uint32_t i = 0; i < allListeners.Size(); i++)
+ {
+ allListeners[i]->OnMostControlMessage(this, r->SourceAddress, r->TargetAddress,
+ r->FBlock, r->Inst, r->Func, r->OpType, r->PayloadLen, r->Payload);
+ }
+ return ISReturn_NoChange;
+}
+