/*
* 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.
*
*/
#include
#include
#include
#include
#include
#include
#include
#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 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;
}