/*
* 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 .
*
* You may also obtain this software under a propriety license from Microchip.
* Please contact Microchip for further information.
*
*/
#include
#include
#include "SafeVector.h"
#include "Network.h"
#include "NetworkDevice.h"
#include "DriverConfiguration.h"
#include "MacAddr.h"
#include "Board.h"
#include "Console.h"
#include "NodeDatabase.h"
#define PRINT_ALL_INFOS()
void CNetwork::OnSync( void *source, bool isSynced )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
ConsolePrintf( PRIO_MEDIUM, "CNetwork::OnSync(deviceInstance:%d, isSynced:%d\n", devInstance, isSynced );
if( isSynced )
{
device->SetNetstate( NetworkState_Unknown );
device->AttachV3();
}
}
void CNetwork::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 )
{
if( NULL == source || !allowNetworkRun )
return;
if (0x100 != nodeAddress && 0x1 != nodeAddress && 0xFFFF != nodeAddress)
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
ConsolePrintf( PRIO_HIGH,
YELLOW"CNetwork::OnNetworkState(inst:%d, mpChanged:%d, " \
"notOk:%d, available:%d, sub:0x%X, trans:0x%X, address:0x%X, pos:%d, " \
"mpr:%d, bw:%d"RESETCOLOR"\n", devInstance, mpValChanged,
systemNotOk, mostAvailable, availableSubState, availableTransition,
nodeAddress, nodePos, maxPos, packetBW );
NetworkState_t curState = device->GetNetState();
if (NetworkState_ShutdownInProgress == curState)
{
ConsolePrintf( PRIO_HIGH, "Ignoring OnNetworkState, because shutdown is still in progress\n");
return;
}
for( uint32_t i = 0; i < allListeners.Size(); i++ )
{
allListeners[i]->OnNetworkState(devInstance, mostAvailable, maxPos, packetBW);
}
if( mostAvailable )
{
if( NetworkState_Available == curState )
{
if( 0x10 == availableSubState )
{
ConsolePrintf( PRIO_ERROR, RED"Unlock detected, shutting down MOST."RESETCOLOR"\n" );
device->SetNetstate( NetworkState_ShutdownInProgress );
device->ClearAllPendingActions();
device->MostNetworkShutdownV3();
return;
}
else if( mpValChanged && 0xFF != maxPos )
{
ConsolePrintf( PRIO_ERROR, RED"MPR change detected, shutting down MOST."RESETCOLOR"\n" );
device->SetNetstate( NetworkState_ShutdownInProgress );
device->ClearAllPendingActions();
device->MostNetworkShutdownV3();
return;
}
else if( 0x11 == availableSubState )
{
ConsolePrintf( PRIO_MEDIUM, YELLOW"CNetwork::OnNetworkState was called with the same mostAvailable (%d) value as before, ignoring.."RESETCOLOR"\n",
mostAvailable );
return;
}
}
}
else
{
if( 0x02 == availableSubState )
{
ConsolePrintf( PRIO_HIGH, YELLOW"INIC enters Ring Break Diagnosis mode!"RESETCOLOR"\n" );
device->GetRingBreakResultV3( 1, 0 );
}
if( NetworkState_Unavailable == curState )
{
ConsolePrintf( PRIO_MEDIUM, YELLOW"CNetwork::OnNetworkState was called with the same mostAvailable (%d) value as before, ignoring.."RESETCOLOR"\n",
mostAvailable );
return;
}
}
bool isTimingMaster = device->IsTimingMaster();
uint32_t asyncBandwidth = device->GetAsyncBandwidth();
if( !mostAvailable )
{
device->SetNetstate( NetworkState_Unavailable );
device->ClearAllPendingActions();
DestroyAllResources( device, 0x1 );
//Clear all existing connection information for this MOST instance
while( true )
{
bool deleted = false;
for( uint16_t i = 0; i < CNodeEntry::GetAmountOfNodeEntries(); i++ )
{
CNodeEntry *entry = CNodeEntry::GetNodeEntry( i );
if( NULL == entry )
continue;
if( devInstance == entry->deviceInstance )
{
for( uint16_t j = 0; j < entry->GetAmountOfConnections(); j++ )
{
CNodeConnectionEntry *connection = entry->GetConnectionByIndex( j );
RaiseUnavailable( connection );
}
CNodeEntry::DeleteNodeEntry( i );
deleted = true;
break;
}
}
if( !deleted )
break;
}
if( 2 == device->GetDeviceApi() )
{
ConsolePrintf( PRIO_ERROR, RED"Error, device API V2 is not supported by "\
"this version of NetworkManager!"RESETCOLOR );
}
else if( 3 == device->GetDeviceApi() && isTimingMaster )
{
ConsolePrintf( PRIO_MEDIUM, "CNetwork::OnNetworkState calling MostNetworkStartupV3\n" );
device->MostNetworkStartupV3( 0xFFFF, asyncBandwidth );
}
else
{
ConsolePrintf( PRIO_ERROR, RED"Error, device API '%d' is not supported by "\
"this version of NetworkManager!"RESETCOLOR, device->GetDeviceApi() );
}
}
else if (asyncBandwidth != packetBW)
{
ConsolePrintf( PRIO_ERROR, RED"Packet Bandwidth does not match."\
" Expected:%d Is:%d, forcing MOST shutdown"RESETCOLOR"\n", asyncBandwidth, packetBW );
device->SetNetstate( NetworkState_ShutdownInProgress );
device->MostNetworkShutdownV3();
}
else if( !systemNotOk
&& ( maxPos <= 64 )
&& ( packetBW <= 372 )
&& ( 0x11 == availableSubState ) )
{
//Everything is ok. Start query network devices
device->SetNetstate( NetworkState_Available );
if( isTimingMaster )
{
device->ToggleNotOk();
}
device->GetGroupAddresses( maxPos );
}
}
void CNetwork::OnNetworkStartupV3( void *source, bool success )
{
CNetworkDevice *device = ( ( CNetworkDevice * )source );
if( success )
{
ConsolePrintf( PRIO_MEDIUM, GREEN"CNetwork::OnNetworkStartupV3 success!"RESETCOLOR"\n" );
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnNetworkStartupV3 failed, retrying.."RESETCOLOR"\n" );
device->ScriptPause(500);
device->MostNetworkStartupV3();
}
}
void CNetwork::OnNetworkShutdownV3( void *source, bool success )
{
CNetworkDevice *device = ( ( CNetworkDevice * )source );
if( success )
{
ConsolePrintf( PRIO_HIGH, GREEN"CNetwork::OnNetworkShutdownV2 success"RESETCOLOR"\n" );
}
else
{
ConsolePrintf( PRIO_ERROR, RED"CNetwork::OnNetworkShutdownV2 failed"RESETCOLOR"\n" );
}
device->SetNetstate( NetworkState_Unknown );
device->InicUnsychronizeV3();
}
void CNetwork::OnMostDeviceType( void *source, bool success, uint16_t nodeAddress, uint16_t deviceType )
{
if( NULL == source )
return;
if( nodeAddress >= 0x400 && nodeAddress <= 0x4FF )
nodeAddress = nodeAddress - 0x300;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnMostDeviceType reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddress );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM, "CNetwork::OnMostDeviceType(deviceInstance:%d, nodeAddress:0x%X, deviceType: 0x%X)\n",
devInstance, nodeAddress, deviceType );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddress );
sem_wait( &vodXmlMutex );
if( ( NULL == entry ) || ( NULL == vodXml ) )
{
sem_post( &vodXmlMutex );
return;
}
entry->deviceType = deviceType;
CSafeVector allChannels;
uint32_t apiVer = vodXml->GetDeviceApi( deviceType );
if( 0xFFFFFFFF == apiVer )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnMostDeviceType reports unknown API version '%d' for"\
" device 0x%X with node address 0x%X, please check GroupAddress in ConfigString or edit configuration file"\
RESETCOLOR"\n", apiVer, deviceType, nodeAddress );
sem_post( &vodXmlMutex );
RaiseUknownConnection( devInstance, nodeAddress, EP_Unknown );
return;
}
else if( 2 == apiVer || apiVer > 3 )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnMostDeviceType reports API version '%d' for"\
" device 0x%X with node address 0x%X, this is not longer supported by this version of NetworkManager"\
RESETCOLOR"\n", apiVer, deviceType, nodeAddress );
sem_post( &vodXmlMutex );
RaiseUknownConnection( devInstance, nodeAddress, EP_Unknown );
return;
}
//Set MAC address regardless if set permanently or not. This MAC address contains MOST specific informations.
//This is necessary, because the bytes in the MAC address are used to identify the streams in the multiplexer.
CMacAddr *macAddress = SetMacAddress( device, devInstance, nodeAddress, apiVer );
if( NULL != macAddress )
{
if( NULL != entry->macAddress )
{
CMacAddr *temp = entry->macAddress;
entry->macAddress = macAddress;
delete temp;
}
else
{
entry->macAddress = macAddress;
}
for( uint16_t i = 0; i < entry->GetAmountOfConnections(); i++ )
{
CNodeConnectionEntry *connection = entry->GetConnectionByIndex( i );
if( NULL != connection )
{
RaiseAvailable( connection );
}
}
}
else
{
ConsolePrintf( PRIO_ERROR, RED"Setting MAC address failed!"RESETCOLOR"\n" );
RaiseUknownConnection( devInstance, nodeAddress, EP_Unknown );
}
if( vodXml->GetChannelConfigurations( deviceType, allChannels ) )
{
if( 0 == allChannels.Size() )
{
RaiseUknownConnection( devInstance, nodeAddress, EP_Unused );
}
else
for( uint32_t i = 0; i < allChannels.Size(); i++ )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( allChannels[i]->channelId, true );
if( NULL == connection->channelConfig )
{
connection->channelConfig = allChannels[i];
}
if( 1 == apiVer )
{
/*------------------------------------*/
/*- INIC API VERSION 1 */
/*------------------------------------*/
if( ( PORT_MLB == connection->channelConfig->inSocket.port )
|| ( PORT_MLB == connection->channelConfig->outSocket.port ) )
{
EPDirection_t direction = EPDIR_Unknown;
CSocketConfiguration *conf = NULL;
if( PORT_MLB == connection->channelConfig->inSocket.port )
{
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
direction = EPDIR_IN;
conf = &connection->channelConfig->inSocket;
}
else
{
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
direction = EPDIR_OUT;
conf = &connection->channelConfig->outSocket;
}
if( !entry->isMlbPortOpened )
{
entry->isMlbPortOpened = true;
device->OpenMlbV1( nodeAddress, vodXml->GetDeviceMlbPortSpeed( deviceType ) );
}
if( 0xFFFFFFFF == conf->splittedOffset )
{
//Normal socket is used
device->CreateMlbSocketV1( nodeAddress, conf->type, direction, conf->address,
conf->blockWidth, allChannels[i]->channelId );
}
else
{
//Enhanced (Splitted) Sockets are used
device->CreateSplittedMlbSocketV1( nodeAddress, conf->type, direction, conf->address,
conf->blockWidth, conf->splittedOffset, conf->subbufferSize,
allChannels[i]->channelId );
}
}
if( ( PORT_TSI == connection->channelConfig->inSocket.port )
|| ( PORT_TSI == connection->channelConfig->outSocket.port ) )
{
EPDirection_t direction = EPDIR_Unknown;
CSocketConfiguration *conf = NULL;
if( PORT_TSI == connection->channelConfig->inSocket.port )
{
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
direction = EPDIR_IN;
conf = &connection->channelConfig->inSocket;
}
else
{
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
direction = EPDIR_OUT;
conf = &connection->channelConfig->outSocket;
}
if( !entry->isTsiPortOpened )
{
entry->isTsiPortOpened = true;
device->OpenTsiV1( nodeAddress, conf->tsiConfig.tsiPortInstance,
conf->tsiConfig.tsiPortMode );
}
device->CreateTsiSocketV1( nodeAddress, conf->tsiConfig.tsiPortInstance, conf->type, direction,
conf->blockWidth, allChannels[i]->channelId );
}
if( ( PORT_I2S == connection->channelConfig->inSocket.port )
|| ( PORT_I2S == connection->channelConfig->outSocket.port ) )
{
EPDirection_t direction = EPDIR_Unknown;
CSocketConfiguration *conf = NULL;
if( PORT_I2S == connection->channelConfig->inSocket.port )
{
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
direction = EPDIR_IN;
conf = &connection->channelConfig->inSocket;
}
else
{
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
direction = EPDIR_OUT;
conf = &connection->channelConfig->outSocket;
}
if( !entry->isI2SPortOpened )
{
if( V1I2sClockModeUnknown != conf->i2sConfig.portClkDriveModeV1
&& V1I2sDataFormatUnknown != conf->i2sConfig.streamingDataFormatV1 )
{
entry->isI2SPortOpened = true;
device->OpenStreamPortV1( nodeAddress, conf->i2sConfig.portClkDriveModeV1,
conf->i2sConfig.portOptionV1, conf->i2sConfig.streamingDataFormatV1,
allChannels[i]->channelId );
}
}
if( 0xFFFFFFFF == conf->splittedOffset )
{
//Normal socket is used
device->CreateStreamSocketV1( nodeAddress, direction, conf->blockWidth, conf->i2sConfig.pinV1,
allChannels[i]->channelId );
}
else
{
//Enhanced (Splitted) Sockets are used
device->CreateSplittedStreamSocketV1( nodeAddress, direction,
conf->blockWidth, conf->splittedOffset, conf->subbufferSize, conf->i2sConfig.pinV1,
allChannels[i]->channelId );
}
}
if( PORT_MOST == connection->channelConfig->outSocket.port )
{
//Open MOST in case of out-connections
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
CSocketConfiguration *conf = &connection->channelConfig->outSocket;
device->CreateMostSocketV1( nodeAddress, conf->type, EPDIR_OUT, conf->address,
conf->blockWidth, allChannels[i]->channelId );
}
else if( ( PORT_MOST == connection->channelConfig->inSocket.port )
&& ( 0xFFFFFFFF != connection->channelConfig->inSocket.address ) )
{
//Or open MOST in case of in-connections with set connection label
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
CSocketConfiguration *conf = &connection->channelConfig->inSocket;
ConsolePrintf( PRIO_MEDIUM,
"Creating MOST socket for preconfigured Connection Label %d (0x%X)\n", conf->address,
conf->address );
device->CreateMostSocketV1( nodeAddress, conf->type, EPDIR_IN, conf->address, conf->blockWidth,
allChannels[i]->channelId );
}
}
else if( 3 == apiVer )
{
/*--------------------------------------------*/
/*-INIC API VERSION 3 (OS81118-D-Rev FW2.3.0) */
/*--------------------------------------------*/
if (0 == i)
device->GetDeviceVersion( nodeAddress );
//Destroy all resources
if( !entry->isUsbPortOpened && ( 0x1 != nodeAddress ) )
{
entry->isUsbPortOpened = true;
device->DeviceSyncV3( nodeAddress, true );
}
if( ( PORT_USB == connection->channelConfig->inSocket.port )
|| ( PORT_USB == connection->channelConfig->outSocket.port ) )
{
EPDirection_t direction = EPDIR_Unknown;
CSocketConfiguration *conf = NULL;
if( PORT_USB == connection->channelConfig->inSocket.port )
{
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
direction = EPDIR_IN;
conf = &connection->channelConfig->inSocket;
}
else
{
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
direction = EPDIR_OUT;
conf = &connection->channelConfig->outSocket;
}
if( 0xFFFFFFFF == conf->splittedOffset )
{
//No Splitter / No Combiner
device->CreateUsbSocketV3( nodeAddress, conf->type, direction, conf->address,
conf->packetsPerTransaction, allChannels[i]->channelId );
}
else
{
//Splitter or Combiner is used
//Do not create multiple USB sockets for a single Splitter / Combiner connection
bool skip = false;
for( uint16_t j = 0; j < entry->GetAmountOfConnections(); j++ )
{
CNodeConnectionEntry *checkConn = entry->GetConnectionByIndex( j );
CSocketConfiguration *checkConf = NULL;
if( EPDIR_IN == direction )
checkConf = &checkConn->channelConfig->inSocket;
else
checkConf = &checkConn->channelConfig->outSocket;
if( ( checkConf != conf ) && ( conf->address == checkConf->address ) )
{
skip = true;
break;
}
}
RaiseAvailable( connection );
if( !skip )
device->CreateSplittedUsbSocketV3( nodeAddress, conf->type, direction, conf->address,
conf->packetsPerTransaction, conf->subbufferSize, allChannels[i]->channelId );
}
}
if( ( PORT_MLB == connection->channelConfig->inSocket.port )
|| ( PORT_MLB == connection->channelConfig->outSocket.port ) )
{
EPDirection_t direction = EPDIR_Unknown;
CSocketConfiguration *conf = NULL;
if( PORT_MLB == connection->channelConfig->inSocket.port )
{
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
direction = EPDIR_IN;
conf = &connection->channelConfig->inSocket;
}
else
{
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
direction = EPDIR_OUT;
conf = &connection->channelConfig->outSocket;
}
if( !entry->isMlbPortOpened )
{
entry->isMlbPortOpened = true;
device->OpenMlbV3( nodeAddress, vodXml->GetDeviceMlbPortSpeed( deviceType ) );
}
if( 0xFFFFFFFF == conf->splittedOffset )
{
//No Splitter / No Combiner
device->CreateMlbSocketV3( nodeAddress, ( uint16_t )0x0A00, //Const value for first instance of MLB bus
conf->type, direction, conf->address, conf->blockWidth, allChannels[i]->channelId );
}
else
{
//Splitter or Combiner is used
//Do not create multiple MLB sockets for a single Splitter / Combiner connection
bool skip = false;
for( uint16_t j = 0; j < entry->GetAmountOfConnections(); j++ )
{
CNodeConnectionEntry *checkConn = entry->GetConnectionByIndex( j );
CSocketConfiguration *checkConf = NULL;
if( EPDIR_IN == direction )
checkConf = &checkConn->channelConfig->inSocket;
else
checkConf = &checkConn->channelConfig->outSocket;
if( ( checkConf != conf ) && ( conf->address == checkConf->address ) )
{
skip = true;
break;
}
}
RaiseAvailable( connection );
if( !skip )
device->CreateSplittedMlbSocketV3( nodeAddress, ( uint16_t )0x0A00, //Const value for first instance of MLB bus
conf->type, direction, conf->address, conf->blockWidth, conf->subbufferSize,
allChannels[i]->channelId );
}
}
if( ( PORT_I2S == connection->channelConfig->inSocket.port )
|| ( PORT_I2S == connection->channelConfig->outSocket.port ) )
{
EPDirection_t direction = EPDIR_Unknown;
CSocketConfiguration *conf = NULL;
uint8_t portInst = 0xFF;
if( PORT_I2S == connection->channelConfig->inSocket.port )
{
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
direction = EPDIR_IN;
conf = &connection->channelConfig->inSocket;
}
else
{
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
direction = EPDIR_OUT;
conf = &connection->channelConfig->outSocket;
}
switch( conf->i2sConfig.pin )
{
case V3I2SSRXA0:
case V3I2SSRXA1:
portInst = 0;
break;
case V3I2SSRXB0:
case V3I2SSRXB1:
portInst = 1;
break;
default:
break;
}
if( !entry->isI2SPortOpened )
{
if( V3I2SOptionUnknown != conf->i2sConfig.portOption )
{
entry->isI2SPortOpened = true;
device->ConfigureStreamPortV3( nodeAddress, 0, conf->i2sConfig.portOption,
conf->i2sConfig.clockMode, conf->i2sConfig.delayMode, allChannels[i]->channelId );
device->ConfigureStreamPortV3( nodeAddress, 1, conf->i2sConfig.portOption,
V3I2SClockModeWildcard, V3I2SDelayWildcard, allChannels[i]->channelId );
}
if( V3I2SSpeedUnknown != conf->i2sConfig.portSpeed )
{
entry->isI2SPortOpened = true;
device->CreateStreamPortV3( nodeAddress, 0, conf->i2sConfig.portSpeed,
conf->i2sConfig.alignment, allChannels[i]->channelId );
device->CreateStreamPortV3( nodeAddress, 1, V3I2SSpeedWildcard,
conf->i2sConfig.alignment, allChannels[i]->channelId );
}
}
if( 0xFFFFFFFF == conf->splittedOffset )
{
//No Splitter / No Combiner
device->CreateStreamSocketV3( nodeAddress, portInst, direction, conf->blockWidth,
conf->i2sConfig.pin, allChannels[i]->channelId );
}
else
{
//Splitter or Combiner is used
//Do not create multiple I2S sockets for a single Splitter / Combiner connection
bool skip = false;
for( uint16_t j = 0; j < entry->GetAmountOfConnections(); j++ )
{
CNodeConnectionEntry *checkConn = entry->GetConnectionByIndex( j );
CSocketConfiguration *checkConf = NULL;
if( EPDIR_IN == direction )
checkConf = &checkConn->channelConfig->inSocket;
else
checkConf = &checkConn->channelConfig->outSocket;
if( ( checkConf != conf ) && ( conf->i2sConfig.pin == checkConf->i2sConfig.pin ) )
{
skip = true;
break;
}
}
RaiseAvailable( connection );
if( !skip )
device->CreateSplittedStreamSocketV3( nodeAddress, portInst, direction,
conf->blockWidth, conf->i2sConfig.pin, conf->subbufferSize,
allChannels[i]->channelId );
}
}
if( PORT_MOST == connection->channelConfig->outSocket.port )
{
//Open MOST in case of out-connections
if( connection->outSocketState != NodeConnection_NotUsed )
continue;
connection->outSocketState = NodeConnection_Pending_Up;
CSocketConfiguration *conf = &connection->channelConfig->outSocket;
device->CreateMostSocketV3( nodeAddress, conf->type, EPDIR_OUT, conf->address,
conf->blockWidth, allChannels[i]->channelId );
}
else if( ( PORT_MOST == connection->channelConfig->inSocket.port )
&& ( 0xFFFFFFFF != connection->channelConfig->inSocket.address ) )
{
//Or open MOST in case of in-connections with set connection label
if( connection->inSocketState != NodeConnection_NotUsed )
continue;
connection->inSocketState = NodeConnection_Pending_Up;
CSocketConfiguration *conf = &connection->channelConfig->inSocket;
ConsolePrintf( PRIO_MEDIUM,
"Creating MOST socket for preconfigured Connection Label %d (0x%X)\n", conf->address,
conf->address );
device->CreateMostSocketV3( nodeAddress, conf->type, EPDIR_IN, conf->address, conf->blockWidth,
allChannels[i]->channelId );
}
}
else
{
ConsolePrintf( PRIO_ERROR, RED"Unknown INIC api version:%d"RESETCOLOR"\n", apiVer );
}
//Perform external script at the end
if( i == ( allChannels.Size() - 1 ) )
{
if( NULL != connection->channelConfig->externalScipt )
{
char configPath[300];
if( NULL != searchPath )
snprintf( configPath, sizeof ( configPath ), "%s/%s", searchPath,
connection->channelConfig->externalScipt );
else
strncpy( configPath, connection->channelConfig->externalScipt, sizeof ( configPath ) );
device->ExecuteMcmScript( nodeAddress, configPath );
}
}
}
}
else
{
ConsolePrintf( PRIO_ERROR,
YELLOW"CNetwork::OnMostDeviceType(deviceType: 0x%X) there is no channel configuration for this device type."RESETCOLOR"\n",
deviceType );
RaiseUknownConnection( devInstance, nodeAddress, EP_Unknown );
}
sem_post( &vodXmlMutex );
}
void CNetwork::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 )
{
assert(EP_Isochron == epType);
if( NULL == source || EP_Isochron != epType )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateTsiSocketV1 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateTsiSocketV1, inst:%d, addr:0x%X, port:%d, type:%d, dir:%d, bwTsi:%d, handle:0x%X, tag:0x%X\n",
devInstance, nodeAddr, tsiPortInst, epType, epDir, blockWidthTsi, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateTsiSocketV1, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
}
TryToConnectSockets( devInstance, nodeAddr, tag );
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateMlbSocketV1 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateMlbSocketV1, inst:%d, addr:0x%X, type:%d, dir:%d, bwMlb:%d, mlbAddr:0x%X, handle:0x%X, tag:0x%X\n", devInstance, nodeAddr, epType, epDir, blockWidthMlb, mlbChannelAddress, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
AimType_t aimType = AIM_UNKNOWN;
uint32_t amountOfBuffers = 0xFFFFFFFF;
uint32_t bufferSize = 0xFFFFFFFF;
uint32_t subbufferSize = 0xFFFFFFFF;
uint32_t packetsPerTransaction = 0xFFFFFFFF;
uint32_t splittedOffset = 0xFFFFFFFF;
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
amountOfBuffers = connection->channelConfig->inSocket.amountOfBuffers;
bufferSize = connection->channelConfig->inSocket.bufferSize;
subbufferSize = connection->channelConfig->inSocket.subbufferSize;
packetsPerTransaction =
connection->channelConfig->inSocket.packetsPerTransaction;
aimType = connection->channelConfig->inSocket.aimType;
splittedOffset = connection->channelConfig->inSocket.splittedOffset;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
amountOfBuffers = connection->channelConfig->outSocket.amountOfBuffers;
bufferSize = connection->channelConfig->outSocket.bufferSize;
subbufferSize = connection->channelConfig->outSocket.subbufferSize;
packetsPerTransaction =
connection->channelConfig->outSocket.packetsPerTransaction;
aimType = connection->channelConfig->outSocket.aimType;
splittedOffset = connection->channelConfig->outSocket.splittedOffset;
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateMlbSocketV1, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
}
if( EP_Asynchron == epType )
{
connection->channelConfig->outSocket.type = EP_Asynchron;
connection->channelConfig->inSocket.type = EP_Asynchron;
connection->inSocketState = NodeConnection_Used;
connection->outSocketState = NodeConnection_Used;
connection->connectedSocketState = NodeConnection_Used;
connection->mostConnectionLabel = 0xA;
}
else if( EP_Unknown == epType || EP_Unused == epType )
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateMlbSocketV1, Channel configuration is invalid, because data type is unknown"RESETCOLOR"\n" );
}
TryToConnectSockets( devInstance, nodeAddr, tag );
if( 0x1 == entry->nodeAddress && ( 0xFFFFFFFF == splittedOffset || 0x0 == splittedOffset ) )
{
connection->bufferSize = bufferSize;
switch( epType )
{
case EP_Synchron:
case EP_Isochron:
device->ConfigureMlbChannel( aimType, mlbChannelAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize,
subbufferSize, packetsPerTransaction );
break;
case EP_Unknown:
case EP_Unused:
//Do nothing
break;
default:
device->ConfigureMlbChannel( mlbChannelAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize );
break;
}
}
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateMostSocketV1 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateMostSocketV1, inst:%d, addr:0x%X, type:%d, dir:%d, bwMost:%d, conLabel:0x%X, handle:0x%X, tag:0x%X\n", devInstance, nodeAddr, epType, epDir, blockwidthMost, connectionLabel, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
connection->mostConnectionLabel = connectionLabel;
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
}
TryToConnectSockets( devInstance, nodeAddr, tag );
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::OnConnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t inSocketHandle,
uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnConnectSocketsV1 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnConnectSocketsV1, inst:%d, addr:0x%X, inHandle:0x%X, outHandle:0x%X, conHandle:0x%X, tag:0x%X\n",
devInstance, nodeAddr, inSocketHandle, outSocketHandle, connectionHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
connection->connectedSocketState = NodeConnection_Used;
connection->connectHandle = connectionHandle;
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::OnDestroySocketV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnDestroySocketV1 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"CNetwork::OnDestroySocketV1(deviceInstance:%d, nodeAddress:0x%X, handle:0x%X, tag:0x%X\n", devInstance,
nodeAddr, handle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
if( ( handle == connection->inHandle ) &&
( NodeConnection_Pending_Down == connection->inSocketState ) )
{
connection->inHandle = ( 0xFFFFFFFF );
connection->inSocketState = NodeConnection_NotUsed;
if( ( NULL != connection->channelConfig )
&& ( PORT_MOST == connection->channelConfig->inSocket.port ) )
{
connection->mostConnectionLabel = 0xFFFFFFFF;
}
}
else if( ( handle == connection->outHandle ) &&
( NodeConnection_Pending_Down == connection->outSocketState ) )
{
connection->outHandle = ( 0xFFFFFFFF );
connection->outSocketState = NodeConnection_NotUsed;
if( ( NULL != connection->channelConfig )
&& ( PORT_MOST == connection->channelConfig->outSocket.port ) )
{
connection->mostConnectionLabel = 0xFFFFFFFF;
}
}
RaiseUnavailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::OnDisconnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnDisconnectSocketsV1 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"CNetwork::OnDisconnectSocketsV1(deviceInstance:%d, nodeAddress:0x%X, handle:0x%X, tag:0x%X\n", devInstance,
nodeAddr, handle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
if( ( handle == connection->connectHandle )
&& ( NodeConnection_Pending_Down == connection->connectedSocketState ) )
{
connection->connectHandle = ( 0xFFFFFFFF );
connection->connectedSocketState = NodeConnection_NotUsed;
}
RaiseUnavailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::OnCreateI2SSocketV1( void *source, bool success, uint16_t nodeAddr, EPDirection_t epDir,
uint16_t blockWidthI2S, V1I2SPin_t pin, uint16_t socketHandle, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateI2SSocketV1 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateI2SSocketV1, addr:0x%X, port:%d, dir:%d, blockwidth:%d, pin:%d, handle:0x%X, tag:0x%X\n",
devInstance, nodeAddr, epDir, blockWidthI2S, pin, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateI2SSocket, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
}
TryToConnectSockets( devInstance, nodeAddr, tag );
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::OnCreateUsbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
EPDirection_t epDir, uint8_t endPointAddress, uint16_t socketHandle, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateUsbSocketV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateUsbSocketV2, inst:%d, addr:0x%X, type:%d, dir:%d, epAddr:%d, handle:0x%X, tag:0x%X\n",
devInstance, nodeAddr, epType, epDir, endPointAddress, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
AimType_t aimType = AIM_UNKNOWN;
uint32_t amountOfBuffers = 0xFFFFFFFF;
uint32_t bufferSize = 0xFFFFFFFF;
uint32_t subbufferSize = 0xFFFFFFFF;
uint32_t packetsPerTransaction = 0xFFFFFFFF;
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
amountOfBuffers = connection->channelConfig->inSocket.amountOfBuffers;
bufferSize = connection->channelConfig->inSocket.bufferSize;
subbufferSize = connection->channelConfig->inSocket.subbufferSize;
packetsPerTransaction =
connection->channelConfig->inSocket.packetsPerTransaction;
aimType = connection->channelConfig->inSocket.aimType;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
amountOfBuffers = connection->channelConfig->outSocket.amountOfBuffers;
bufferSize = connection->channelConfig->outSocket.bufferSize;
subbufferSize = connection->channelConfig->outSocket.subbufferSize;
packetsPerTransaction =
connection->channelConfig->outSocket.packetsPerTransaction;
aimType = connection->channelConfig->outSocket.aimType;
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateUsbSocketV2, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
}
TryToConnectSockets( devInstance, nodeAddr, tag );
if( 0x1 == entry->nodeAddress )
{
switch( epType )
{
case EP_Synchron:
connection->bufferSize = bufferSize;
device->ConfigureUsbEndpoint( aimType, endPointAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize,
subbufferSize, packetsPerTransaction );
break;
case EP_Isochron:
connection->bufferSize = bufferSize;
device->ConfigureUsbEndpoint( aimType, endPointAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize,
subbufferSize, packetsPerTransaction );
break;
case EP_Unknown:
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateUsbSocketV2, Channel configuration is invalid, because data type is unknown"RESETCOLOR"\n" );
break;
default:
connection->bufferSize = bufferSize;
device->ConfigureUsbEndpoint( endPointAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize );
break;
}
}
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateSplittedUsbSocketV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateSplittedUsbSocketV2, inst:%d, addr:0x%X, type:%d, dir:%d, epAddr:%d, USB-handle:0x%X, Splitter-handle:0x%X, tag:0x%X\n", devInstance, nodeAddr, epType, epDir, endPointAddress, usbHandle, splitterHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, false );
if( NULL != connection )
{
AimType_t aimType = AIM_UNKNOWN;
uint32_t amountOfBuffers = 0xFFFFFFFF;
uint32_t bufferSize = 0xFFFFFFFF;
uint32_t subbufferSize = 0xFFFFFFFF;
uint32_t packetsPerTransaction = 0xFFFFFFFF;
bool valSet = false;
for( uint16_t j = 0; j < entry->GetAmountOfConnections(); j++ )
{
CNodeConnectionEntry *checkConn = entry->GetConnectionByIndex( j );
if( EPDIR_IN == epDir )
{
if( connection->channelConfig->inSocket.address != checkConn->channelConfig->inSocket.address )
continue;
checkConn->inSocketState = NodeConnection_Used;
checkConn->inHandle = splitterHandle;
checkConn->splittedSourceHandle = usbHandle;
if( !valSet )
{
valSet = true;
amountOfBuffers = checkConn->channelConfig->inSocket.amountOfBuffers;
bufferSize = checkConn->channelConfig->inSocket.bufferSize;
subbufferSize = checkConn->channelConfig->inSocket.subbufferSize;
packetsPerTransaction =
checkConn->channelConfig->inSocket.packetsPerTransaction;
aimType = connection->channelConfig->inSocket.aimType;
}
TryToConnectSockets( devInstance, nodeAddr, checkConn->channelId );
}
else if( EPDIR_OUT == epDir )
{
if( connection->channelConfig->outSocket.address != checkConn->channelConfig->outSocket.address )
continue;
checkConn->outSocketState = NodeConnection_Used;
checkConn->outHandle = splitterHandle;
checkConn->splittedSourceHandle = usbHandle;
if( !valSet )
{
valSet = true;
amountOfBuffers = checkConn->channelConfig->outSocket.amountOfBuffers;
bufferSize = checkConn->channelConfig->outSocket.bufferSize;
subbufferSize = checkConn->channelConfig->outSocket.subbufferSize;
packetsPerTransaction =
checkConn->channelConfig->outSocket.packetsPerTransaction;
aimType = connection->channelConfig->outSocket.aimType;
}
TryToConnectSockets( devInstance, nodeAddr, checkConn->channelId );
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateUsbSocketV2, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
return;
}
}
if( 0x1 == entry->nodeAddress )
{
switch( epType )
{
case EP_Synchron:
connection->bufferSize = bufferSize;
device->ConfigureUsbEndpoint( aimType, endPointAddress, epType, epDir,
connection->deviceName, sizeof ( connection->deviceName ), amountOfBuffers, bufferSize,
subbufferSize, packetsPerTransaction );
break;
case EP_Isochron:
connection->bufferSize = bufferSize;
device->ConfigureUsbEndpoint( aimType, endPointAddress, epType, epDir,
connection->deviceName, sizeof ( connection->deviceName ), amountOfBuffers, bufferSize,
subbufferSize, packetsPerTransaction );
break;
case EP_Unknown:
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateUsbSocketV2, Channel configuration is invalid, because data type is unknown"RESETCOLOR"\n" );
break;
default:
connection->bufferSize = bufferSize;
device->ConfigureUsbEndpoint( endPointAddress, epType, epDir,
connection->deviceName, sizeof ( connection->deviceName ), amountOfBuffers, bufferSize );
break;
}
}
RaiseAvailable( connection );
}
PRINT_ALL_INFOS();
}
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateMlbSocketV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateMlbSocketV2, inst:%d, addr:0x%X, type:%d, dir:%d, mlbAddr:%d, handle:0x%X, tag:0x%X\n",
devInstance, nodeAddr, epType, epDir, mlbChannelAddress, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
AimType_t aimType = AIM_UNKNOWN;
uint32_t amountOfBuffers = 0xFFFFFFFF;
uint32_t bufferSize = 0xFFFFFFFF;
uint32_t subbufferSize = 0xFFFFFFFF;
uint32_t packetsPerTransaction = 0xFFFFFFFF;
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
amountOfBuffers = connection->channelConfig->inSocket.amountOfBuffers;
bufferSize = connection->channelConfig->inSocket.bufferSize;
subbufferSize = connection->channelConfig->inSocket.subbufferSize;
packetsPerTransaction =
connection->channelConfig->inSocket.packetsPerTransaction;
aimType = connection->channelConfig->inSocket.aimType;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
amountOfBuffers = connection->channelConfig->outSocket.amountOfBuffers;
bufferSize = connection->channelConfig->outSocket.bufferSize;
subbufferSize = connection->channelConfig->outSocket.subbufferSize;
packetsPerTransaction =
connection->channelConfig->outSocket.packetsPerTransaction;
aimType = connection->channelConfig->outSocket.aimType;
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateMlbSocketV2, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
}
TryToConnectSockets( devInstance, nodeAddr, tag );
if( 0x1 == entry->nodeAddress )
{
connection->bufferSize = bufferSize;
switch( epType )
{
case EP_Synchron:
case EP_Isochron:
device->ConfigureMlbChannel( aimType, mlbChannelAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize,
subbufferSize, packetsPerTransaction );
break;
case EP_Unknown:
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateMlbSocketV2, Channel configuration is invalid, because data type is unknown"RESETCOLOR"\n" );
break;
default:
device->ConfigureMlbChannel( mlbChannelAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize );
break;
}
}
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateSplittedMlbSocketV3 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateSplittedMlbSocketV3, inst:%d, addr:0x%X, type:%d, dir:%d, mlbAddr:%d, mlb-handle:0x%X, Splitter-handle:0x%X, tag:0x%X\n", devInstance, nodeAddr, epType, epDir, mlbChannelAddress, mlbSocketHandle, splitterHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
AimType_t aimType = AIM_UNKNOWN;
uint32_t amountOfBuffers = 0xFFFFFFFF;
uint32_t bufferSize = 0xFFFFFFFF;
uint32_t subbufferSize = 0xFFFFFFFF;
uint32_t packetsPerTransaction = 0xFFFFFFFF;
bool valSet = false;
for( uint16_t j = 0; j < entry->GetAmountOfConnections(); j++ )
{
CNodeConnectionEntry *checkConn = entry->GetConnectionByIndex( j );
if( EPDIR_IN == epDir )
{
if( connection->channelConfig->inSocket.address != checkConn->channelConfig->inSocket.address )
continue;
checkConn->inSocketState = NodeConnection_Used;
checkConn->inHandle = splitterHandle;
checkConn->splittedSourceHandle = mlbSocketHandle;
if( !valSet )
{
valSet = true;
amountOfBuffers = checkConn->channelConfig->inSocket.amountOfBuffers;
bufferSize = checkConn->channelConfig->inSocket.bufferSize;
subbufferSize = checkConn->channelConfig->inSocket.subbufferSize;
packetsPerTransaction =
checkConn->channelConfig->inSocket.packetsPerTransaction;
aimType = connection->channelConfig->inSocket.aimType;
}
TryToConnectSockets( devInstance, nodeAddr, checkConn->channelId );
}
else if( EPDIR_OUT == epDir )
{
if( connection->channelConfig->outSocket.address != checkConn->channelConfig->outSocket.address )
continue;
checkConn->outSocketState = NodeConnection_Used;
checkConn->outHandle = splitterHandle;
checkConn->splittedSourceHandle = mlbSocketHandle;
if( !valSet )
{
valSet = true;
amountOfBuffers = checkConn->channelConfig->outSocket.amountOfBuffers;
bufferSize = checkConn->channelConfig->outSocket.bufferSize;
subbufferSize = checkConn->channelConfig->outSocket.subbufferSize;
packetsPerTransaction =
checkConn->channelConfig->outSocket.packetsPerTransaction;
aimType = connection->channelConfig->outSocket.aimType;
}
TryToConnectSockets( devInstance, nodeAddr, checkConn->channelId );
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateSplittedMlbSocketV3, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
return;
}
}
if( 0x1 == entry->nodeAddress )
{
connection->bufferSize = bufferSize;
switch( epType )
{
case EP_Synchron:
case EP_Isochron:
device->ConfigureMlbChannel( aimType, mlbChannelAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize,
subbufferSize, packetsPerTransaction );
break;
case EP_Unknown:
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateMlbSocketV2, Channel configuration is invalid, because data type is unknown"RESETCOLOR"\n" );
break;
default:
device->ConfigureMlbChannel( mlbChannelAddress, epType, epDir,
connection->deviceName, sizeof( connection->deviceName ), amountOfBuffers, bufferSize );
break;
}
}
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateI2SSocket reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateI2SSocket, inst:%d, addr:0x%X, port:%d, dir:%d, blockwidth:%d, pin:%d, handle:0x%X, tag:0x%X\n", devInstance, nodeAddr, portInstance, epDir, blockWidthI2S, pin, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateI2SSocket, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
}
TryToConnectSockets( devInstance, nodeAddr, tag );
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateSplittedI2SSocketV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateI2SSocket, inst:%d, addr:0x%X, port:%d, dir:%d, blockwidth:%d, pin:%d, i2s-handle:0x%X, Splitter-handle:0x%X, tag:0x%X\n", devInstance, nodeAddr, portInstance, epDir, blockWidthI2S, pin, i2sSocketHandle, splitterHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
if( EPDIR_IN == epDir )
{
//Find all related pin configurations, this is the use case of splitted I2S sockets
V3I2SPin_t pin = connection->channelConfig->inSocket.i2sConfig.pin;
uint16_t all = entry->GetAmountOfConnections();
for (uint16_t i = 0; i < all; i++)
{
CNodeConnectionEntry *con = entry->GetConnectionByIndex(i);
if (pin == con->channelConfig->inSocket.i2sConfig.pin)
{
con->inSocketState = NodeConnection_Used;
con->inHandle = splitterHandle;
con->splittedSourceHandle = i2sSocketHandle;
TryToConnectSockets( devInstance, nodeAddr, con->channelId );
}
}
}
else if( EPDIR_OUT == epDir )
{
//Find all related pin configurations, this is the use case of splitted I2S sockets
V3I2SPin_t pin = connection->channelConfig->outSocket.i2sConfig.pin;
uint16_t all = entry->GetAmountOfConnections();
for (uint16_t i = 0; i < all; i++)
{
CNodeConnectionEntry *con = entry->GetConnectionByIndex(i);
if (pin == con->channelConfig->outSocket.i2sConfig.pin)
{
con->outSocketState = NodeConnection_Used;
con->outHandle = splitterHandle;
con->splittedSourceHandle = i2sSocketHandle;
TryToConnectSockets( devInstance, nodeAddr, con->channelId );
}
}
}
else
{
ConsolePrintf(
PRIO_ERROR, RED"Network::OnCreateI2SSocket, Channel configuration is invalid, because direction of stream is unknown"RESETCOLOR"\n" );
}
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateMostSocketV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnCreateMostSocketV2, inst:%d, addr:0x%X, type:%d, dir:%d, bwMost:%d, conLabel:0x%X, handle:0x%X, tag:0x%X\n", devInstance, nodeAddr, epType, epDir, blockwidthMost, connectionLabel, socketHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
connection->mostConnectionLabel = connectionLabel;
if( EPDIR_IN == epDir )
{
connection->inSocketState = NodeConnection_Used;
connection->inHandle = socketHandle;
}
else if( EPDIR_OUT == epDir )
{
connection->outSocketState = NodeConnection_Used;
connection->outHandle = socketHandle;
}
TryToConnectSockets( devInstance, nodeAddr, tag );
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::OnConnectSocketsV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
uint16_t inSocketHandle, uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnConnectSocketsV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
ConsolePrintf( PRIO_MEDIUM,
"Network::OnConnectSocketsV2, inst:%d, addr:0x%X, Type0x%X, inHandle:0x%X, outHandle:0x%X, conHandle:0x%X, tag:0x%X\n", devInstance, nodeAddr, epType, inSocketHandle, outSocketHandle, connectionHandle, tag );
CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
if( NULL != entry )
{
CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( tag, true );
if( NULL != connection )
{
connection->connectedSocketState = NodeConnection_Used;
connection->connectHandle = connectionHandle;
RaiseAvailable( connection );
}
}
PRINT_ALL_INFOS();
}
void CNetwork::OnControlChannelReadEnd( void *source )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
connectionBitMask = connectionBitMask & ~( 1 << devInstance );
ConsolePrintf( PRIO_ERROR, RED"Destroying NetworkDevice with instance %d, because the reader thread has ended"RESETCOLOR"\n",
devInstance );
allNetworkDevices.Remove(device);
delete device;
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
for( uint32_t i = 0; i < allListeners.Size(); i++ )
{
allListeners[i]->OnMostControlMessage( devInstance, sourceAddr, targetAddr, nFBlock, nInst, nFunc, nOpType,
nPayloadLen, Payload );
}
}
void CNetwork::OnRbdResultV3( void *source, uint16_t nodeAddress, uint8_t result, uint8_t position,
uint8_t status, uint16_t id )
{
CNetworkDeviceListener::OnRbdResultV3( source, nodeAddress, result, position, status, id );
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
for( uint32_t i = 0; i < allListeners.Size(); i++ )
{
allListeners[i]->OnRingBreakDiagnosisResultV3( devInstance, nodeAddress, result, position, status, id );
}
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnMostMacAddress reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddress );
ShutdownMostBecauseOfErrors( device );
return;
}
}
void CNetwork::OnConfigureI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
V3I2SPortOption_t option, V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnConfigureI2SPortV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
ShutdownMostBecauseOfErrors( device );
return;
}
}
void CNetwork::OnCreateI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
V3I2SPortSpeed_t clock, V3I2SAlignment_t align, uint32_t tag )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnCreateI2SPortV2 reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, nodeAddr );
return;
}
}
void CNetwork::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 )
{
if( NULL == source )
return;
CNetworkDevice *device = ( ( CNetworkDevice * )source );
uint32_t devInstance = device->GetDeviceIndex();
if( !success )
{
ConsolePrintf(
PRIO_ERROR, RED"CNetwork::OnDeviceVersion reports failure for device:%d, nodeAddress:0x%X"RESETCOLOR"\n",
devInstance, sourceAddr );
return;
}
ConsolePrintf( PRIO_MEDIUM, "Got Device version for nodeAddress:0x%X, productId:0x%X, fwVersion:0x%X, "\
"buildVersion:0x%X, hwVersion:%d, diagnosisId:0x%X\n", sourceAddr, productId, fwVersion,
buildVersion, hwVersion, diagnosisId);
if( 0x81118 == productId )
{
uint8_t exMajor = 2;
uint8_t exMinor = 4;
uint8_t exRelease = 0;
uint32_t expectedFW = exMajor << 24 | exMinor << 16 | exRelease << 8;
if (fwVersion < expectedFW)
{
ConsolePrintf( PRIO_ERROR, RED"Warning, the device with node address:0x%X uses"\
" too old firmware! Please update to: V%d.%d.%d"RESETCOLOR"\n",
sourceAddr, exMajor, exMinor, exRelease);
}
}
}