diff options
Diffstat (limited to 'Src/Network/IndustrialStack_ApiV3.h')
-rw-r--r-- | Src/Network/IndustrialStack_ApiV3.h | 1123 |
1 files changed, 1123 insertions, 0 deletions
diff --git a/Src/Network/IndustrialStack_ApiV3.h b/Src/Network/IndustrialStack_ApiV3.h new file mode 100644 index 0000000..7e37789 --- /dev/null +++ b/Src/Network/IndustrialStack_ApiV3.h @@ -0,0 +1,1123 @@ +/* + * 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. + * + */ + +/*----------------------------------------------------------*/ +/*! \file + * \brief This file contains the CIndustrialStack class (API V3 commands). + */ +/*----------------------------------------------------------*/ + +#ifndef INDUSTRIAL_STACK_API_V3_H +#define INDUSTRIAL_STACK_API_V3_H + +#include "IndustrialStack.h" +#include "Network.h" +#include "Types.h" + +class CV3_OnMostRx : public CSInternalEvent +{ +private: + CNetworkDevice *device; +public: + CV3_OnMostRx(CNetworkDevice *d) : device(d) + { + } + + virtual ISReturn_t OnMostMessage(CIndustrialStack *iStack, CISMostMsg *r) + { + assert(NULL != device); + assert(r->IsValid); + if (0x0 == r->FBlock) //INIC Block + { + switch (r->Func) + { + case 0x520: //MOST Network Status + if (CISOpType_STATUS == r->OpType && r->PayloadLen == 11) + { + bool mpValChanged = ( 0 != ( r->Payload[1] & 0x1 ) ); //This is a 16 Bit value!! + bool systemNotOk = false; //Not transmitted any longer + bool mostAvailable = ( 0 != ( r->Payload[2] & 0x1 ) ); + uint8_t availableSubState = r->Payload[3]; + uint8_t availableTransition = r->Payload[4]; + uint16_t nodeAddress = r->Payload[5] << 8 + | r->Payload[6]; + uint8_t nodePos = ( r->Payload[7] & 0x3F ); + uint8_t maxPos = ( r->Payload[8] ); + uint16_t packetBW = r->Payload[9] << 8 + | r->Payload[10]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnNetworkState(device, + mpValChanged, systemNotOk, mostAvailable, availableSubState, + availableTransition, nodeAddress, nodePos, maxPos, packetBW); + } + break; + case 0x524: //MOST Network Startup + if (CISOpType_STATUS == r->OpType) + { + if (r->Payload[0] == 0x20 && r->Payload[1] == 0x04 && r->Payload[2] == 0x40) + return ISReturn_NoChange; //Startup was called, but we already have locked network, so ignore this error + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnNetworkStartupV3(device, (CISOpType_STATUS == r->OpType)); + } + break; + case 0x527: //RBD Result + if (CISOpType_STATUS == r->OpType && r->PayloadLen == 5) + { + uint8_t result = r->Payload[0]; + uint8_t position = r->Payload[1]; + uint8_t status = r->Payload[2]; + uint16_t id = r->Payload[3] << 8 + | r->Payload[4]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnRbdResultV3(device, r->SourceAddress, + result, position, status, id); + } + break; + } + } + else if (0x1 == r->FBlock) //NetBlock FBlock + { + switch (r->Func) + { + case 0x004: //GroupAddress Changed + if (CISOpType_STATUS == r->OpType && r->PayloadLen >= 2) + { + uint16_t groupAddress = r->Payload[0] << 8 + | r->Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnMostDeviceType(device, true, r->SourceAddress, groupAddress ); + } + else if (CISOpType_ERROR == r->OpType) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnMostDeviceType(device, false, r->SourceAddress, 0xFFFF ); + } + break; + case 0x013: //NetBlock EUI48 + if (CISOpType_STATUS == r->OpType && r->PayloadLen >= 6) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnMostMacAddress(device, true, + r->SourceAddress, r->Payload[0], r->Payload[1], + r->Payload[2], r->Payload[3], r->Payload[4], r->Payload[5]); + } + else if (CISOpType_ERROR == r->OpType) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnMostMacAddress(device, false, + r->SourceAddress, 0,0,0,0,0,0); + } + break; + } + } + return ISReturn_NoChange; + } + + virtual void OnSyncStateChanged(CIndustrialStack *iStack, bool isSynced) + { + assert(NULL != device); + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnSync(device, isSynced ); + } +}; + +class CV3_NetworkStartup : public CISSendMostMsgElement +{ +private: + CNetworkDevice *device; +public: + CV3_NetworkStartup(CNetworkDevice *d, uint16_t autoForcedNotAvailable, uint16_t packetBW) : device(d) + { + ElementName = "CV3_NetworkStartup"; + WaitForResponseOpType = CISOpType_RESULT; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = 0x1; + Request.FBlock = 0x0; + Request.Func = 0x524; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 4; + Request.Payload[0] = autoForcedNotAvailable / 256; + Request.Payload[1] = autoForcedNotAvailable % 256; + Request.Payload[2] = packetBW / 256; + Request.Payload[3] = packetBW % 256; + } +}; + +class CV3_MostNetworkConfiguration : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; +public: + CV3_MostNetworkConfiguration(CNetworkDevice *d, uint16_t nodeAddress, + uint8_t macAddress1, uint8_t macAddress2, uint8_t macAddress3, + uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6, + bool promiscuous) : device(d) + { + ElementName = "CV3_MostNetworkConfiguration"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_STATUS; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x521; + Request.Inst = 0x00; + Request.OpType = CISOpType_SETGET; + Request.PayloadLen = 24; + Request.Payload[0] = 0; // HB: MASK + Request.Payload[1] = + ( 1 << 3 ) // LB: MASK: Packet Filter Mode is considered + | ( 1 << 5 ); // LB: MASK: PacketEUI is considered + Request.Payload[2] = 0x00; // HB: Node Address (ignored) + Request.Payload[3] = 0x08; // LB: Node Address (ignored) + Request.Payload[4] = 0x00; // HB: Group Address (ignored) + Request.Payload[5] = 0x00; // LB: Group Address (ignored) + Request.Payload[6] = 0x00; // Control LLR Block Count (ignored) + Request.Payload[7] = 0x00; // HB: FilterMode (reserved) + Request.Payload[8] = promiscuous ? 0x0A : 0x08; // LB: FilterMode (Allow all Multicast) + Request.Payload[9] = 0x00; // HB: PacketHash_63to48 (ignored) + Request.Payload[10] = 0x00; // LB: PacketHash_63to48 (ignored) + Request.Payload[11] = 0x00; // HB: PacketHash_47to32 (ignored) + Request.Payload[12] = 0x00; // LB: PacketHash_47to32 (ignored) + Request.Payload[13] = 0x00; // HB: PacketHash_31to16 (ignored) + Request.Payload[14] = 0x00; // LB: PacketHash_31to16 (ignored) + Request.Payload[15] = 0x00; // HB: PacketHash_15to0 (ignored) + Request.Payload[16] = 0x00; // LB: PacketHash_15to0 (ignored) + Request.Payload[17] = macAddress1; // HB: PacketEUI48_47to32 + Request.Payload[18] = macAddress2; // LB: PacketEUI48_47to32 + Request.Payload[19] = macAddress3; // HB: PacketEUI48_31to16 + Request.Payload[20] = macAddress4; // LB: PacketEUI48_31to16 + Request.Payload[21] = macAddress5; // HB: PacketEUI48_15to0 + Request.Payload[22] = macAddress6; // LB: PacketEUI48_15to0 + Request.Payload[23] = 0x00; // PacketLLRTime (ignored) + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + assert(this == element); + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 18; + if (success) + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnMostMacAddress(device, true, + Request.TargetAddress, Response.Payload[15],Response.Payload[16], + Response.Payload[17], Response.Payload[18], Response.Payload[19], + Response.Payload[20]); + else + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnMostMacAddress(device, false, + Request.TargetAddress, 0, 0, 0, 0, 0, 0); + } +}; + +class CV3_DeviceAttach : public CISSendMostMsgElement +{ +public: + CV3_DeviceAttach() + { + ElementName = "CV3_DeviceAttach"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = 0x1; + Request.FBlock = 0x0; + Request.Func = 0x223; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + } +}; + +class CV3_Unsynchronize : public IISElement +{ +public: + CV3_Unsynchronize() + { + ElementName = "CV3_Unsynchronize"; + } + + virtual ISReturn_t Service(CIndustrialStack *iStack, uint32_t time) + { + assert(NULL != iStack); + iStack->Unsynchronize(); + return ISReturn_Success; + } + + virtual ISReturn_t OnMostMessage(CIndustrialStack *iStack, CISMostMsg *r) + { + return ISReturn_NoChange; + } +}; + +class CV3_DeviceSync : public CISSendMostMsgElement +{ +public: + CV3_DeviceSync(uint16_t nodeAddress, bool sync) + { + if (0x1 == nodeAddress) + { + ConsolePrintf(PRIO_ERROR, RED"CV3_DeviceSync was called with local" \ + " node address, this will fail!"RESETCOLOR"\n"); + } + ElementName = "CV3_DeviceSync"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x224; + Request.Inst = 0x01; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 1; + Request.Payload[0] = sync; + } +}; + +class CV3_NetworkShutdown : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; +public: + CV3_NetworkShutdown(CNetworkDevice *d) : device(d) + { + ElementName = "CV3_NetworkShutdown"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = 0x1; + Request.FBlock = 0x0; + Request.Func = 0x525; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 0; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnNetworkShutdownV3(device, (ISReturn_Success == result)); + } +}; + +class CV3_MlbPortCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; +public: + CV3_MlbPortCreate(CNetworkDevice *d, uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed) : device(d) + { + ElementName = "CV3_MlbPortCreate"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x621; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 2; + Request.Payload[0] = 0x00; //Index + Request.Payload[1] = mlbSpeed; //ClockConfig + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + uint16_t mlbPortHandle = 0xFFFF; + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (success) + mlbPortHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnOpenMlbV3(device, success, Request.TargetAddress, mlbPortHandle); + } +}; + +class CV3_UsbSocketCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + EPDataType_t epType; + EPDirection_t epDir; + uint8_t endPointAddress; + uint16_t packetsPerFrame; + uint32_t tag; +public: + CV3_UsbSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, EPDataType_t ept, + EPDirection_t epd, uint8_t epa, uint16_t p, uint32_t t) : device(d), epType(ept), + epDir(epd), endPointAddress(epa), packetsPerFrame(p), tag(t) + { + ElementName = "CV3_UsbSocketCreate"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x671; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 7; + Request.Payload[0] = 0x12; // HB: UsbPortHandle + Request.Payload[1] = 0x00; // LB: UsbPortHandle + Request.Payload[2] = epDir; // Direction + Request.Payload[3] = epType; // DataType + Request.Payload[4] = endPointAddress; // EndpointAddress + Request.Payload[5] = packetsPerFrame / 256; // HB: Packets per USB frame + Request.Payload[6] = packetsPerFrame % 256; // LB: Packets per USB frame + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + uint16_t usbHandle = 0xFFFF; + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (success) + usbHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateUsbSocketV3(device, success, + Request.TargetAddress, epType, epDir, endPointAddress, usbHandle, tag); + } +}; + +class CV3_SplittedUsbSocketCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + EPDataType_t epType; + EPDirection_t epDir; + uint8_t endPointAddress; + uint16_t packetsPerUsbFrame; + uint16_t bytesPerPacket; + uint32_t tag; + uint16_t usbHandle; +public: + CV3_SplittedUsbSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, EPDataType_t ept, + EPDirection_t epd, uint8_t epa, uint16_t p, uint16_t bp, uint32_t t) : device(d), epType(ept), + epDir(epd), endPointAddress(epa), packetsPerUsbFrame(p), bytesPerPacket(bp), tag(t), + usbHandle(0xFFFF) + { + ElementName = "CV3_SplittedUsbSocketCreate-USB"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x671; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 7; + Request.Payload[0] = 0x12; // HB: UsbPortHandle + Request.Payload[1] = 0x00; // LB: UsbPortHandle + Request.Payload[2] = epDir; // Direction + Request.Payload[3] = epType; // DataType + Request.Payload[4] = endPointAddress; // EndpointAddress + Request.Payload[5] = packetsPerUsbFrame / 256; // HB: Packets per USB frame + Request.Payload[6] = packetsPerUsbFrame % 256; // LB: Packets per USB frame + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (!success) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateSplittedUsbSocketV3(device, false, + Request.TargetAddress, epType, epDir, endPointAddress, 0xFFFF, 0xFFFF, tag); + return; + } + if (0x671 == Response.Func) + { + usbHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + CreateSplitter(iStack); + } + else + { + uint16_t splitterHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateSplittedUsbSocketV3(device, success, + Request.TargetAddress, epType, epDir, endPointAddress, usbHandle, splitterHandle, tag); + } + } +private: + void CreateSplitter(CIndustrialStack *iStack) + { + assert(usbHandle != 0xFFFF); + ElementName = "CV3_SplittedUsbSocketCreate-Splitter"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + startTime = 0; + Request.FBlock = 0x0; + if( EPDIR_IN == epDir ) + Request.Func = 0x911; //SplitterCreate + else + Request.Func = 0x901; //CombinerCreate + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 6; + Request.Payload[0] = usbHandle / 256; // HB: SocketHandle IN/OUT + Request.Payload[1] = usbHandle % 256; // LB: SocketHandle IN/OUT + Request.Payload[2] = 0x0D; // HB: MOSTPortHandle + Request.Payload[3] = 0x00; // LB: MOSTPortHandle + Request.Payload[4] = bytesPerPacket / 256; // HB: BytesPerFrame + Request.Payload[5] = bytesPerPacket % 256; // LB: BytesPerFrame + iStack->EnqueueElement(Request.TargetAddress, this); + } +}; + +class CV3_MlbSocketCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint16_t mlbPortHandle; + EPDataType_t epType; + EPDirection_t epDir; + uint8_t mlbChannelAddress; + uint16_t blockWidthMlb; + uint32_t tag; +public: + CV3_MlbSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, uint16_t mlb, EPDataType_t ept, + EPDirection_t epd, uint8_t eca, uint16_t bw, uint32_t t) : device(d), mlbPortHandle(mlb), + epType(ept), epDir(epd), mlbChannelAddress(eca), blockWidthMlb(bw), tag(t) + { + ElementName = "CV3_MlbSocketCreate"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x631; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 8; + Request.Payload[0] = mlbPortHandle / 256; + Request.Payload[1] = mlbPortHandle % 256; + Request.Payload[2] = epDir; + Request.Payload[3] = epType; + Request.Payload[4] = blockWidthMlb / 256; + Request.Payload[5] = blockWidthMlb % 256; + Request.Payload[6] = mlbChannelAddress / 256; + Request.Payload[7] = mlbChannelAddress % 256; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + uint16_t mlbHandle = 0xFFFF; + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (success) + mlbHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateMlbSocketV3(device, success, + Request.TargetAddress, epType, epDir, blockWidthMlb, mlbChannelAddress, mlbHandle, tag); + } +}; + +class CV3_SplittedMlbSocketCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint16_t mlbPortHandle; + EPDataType_t epType; + EPDirection_t epDir; + uint8_t mlbChannelAddress; + uint16_t blockWidthMlb; + uint16_t bytesPerPacket; + uint16_t mlbHandle; + uint32_t tag; +public: + CV3_SplittedMlbSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, uint16_t mlb, EPDataType_t ept, + EPDirection_t epd, uint8_t eca, uint16_t bw, uint16_t bp, uint32_t t) : device(d), mlbPortHandle(mlb), + epType(ept), epDir(epd), mlbChannelAddress(eca), blockWidthMlb(bw), bytesPerPacket(bp), tag(t) + { + ElementName = "CV3_SplittedMlbSocketCreate-MLB"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x631; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 8; + Request.Payload[0] = mlbPortHandle / 256; + Request.Payload[1] = mlbPortHandle % 256; + Request.Payload[2] = epDir; + Request.Payload[3] = epType; + Request.Payload[4] = blockWidthMlb / 256; + Request.Payload[5] = blockWidthMlb % 256; + Request.Payload[6] = mlbChannelAddress / 256; + Request.Payload[7] = mlbChannelAddress % 256; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (!success) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateSplittedMlbSocketV3(device, false, + Request.TargetAddress, epType, epDir, blockWidthMlb, mlbChannelAddress, + 0xFFFF, 0xFFFF, tag); + return; + } + if (0x631 == Response.Func) + { + mlbHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + CreateSplitter(iStack); + } + else + { + uint16_t splitterHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateSplittedMlbSocketV3(device, success, + Request.TargetAddress, epType, epDir, blockWidthMlb, mlbChannelAddress, + mlbHandle, splitterHandle, tag); + } + } +private: + void CreateSplitter(CIndustrialStack *iStack) + { + assert(mlbHandle != 0xFFFF); + ElementName = "CV3_SplittedMlbSocketCreate-Splitter"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + startTime = 0; + Request.FBlock = 0x0; + if( EPDIR_IN == epDir ) + Request.Func = 0x911; //SplitterCreate + else + Request.Func = 0x901; //CombinerCreate + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 6; + Request.Payload[0] = mlbHandle / 256; // HB: SocketHandle IN/OUT + Request.Payload[1] = mlbHandle % 256; // LB: SocketHandle IN/OUT + Request.Payload[2] = 0x0D; // HB: MOSTPortHandle + Request.Payload[3] = 0x00; // LB: MOSTPortHandle + Request.Payload[4] = bytesPerPacket / 256; // HB: BytesPerFrame + Request.Payload[5] = bytesPerPacket % 256; // LB: BytesPerFrame + iStack->EnqueueElement(Request.TargetAddress, this); + } +}; + +class CV3_MostSocketCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint16_t nodeAddress; + EPDataType_t epType; + EPDirection_t epDir; + uint16_t connectionLabel; + uint16_t blockwidthMost; + uint32_t tag; +public: + CV3_MostSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, EPDataType_t ep, EPDirection_t epd, + uint16_t cl, uint16_t bw, uint32_t t) : device(d), epType(ep), + epDir(epd), connectionLabel(cl), blockwidthMost(bw), tag(t) + { + ElementName = "CV3_MostSocketCreate"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x611; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 8; + Request.Payload[0] = 0x0D; // HB: MostPortHandle + Request.Payload[1] = 0x00; // LB: MostPortHandle + Request.Payload[2] = epDir; // Dir + Request.Payload[3] = epType; // DataType + Request.Payload[4] = blockwidthMost / 256; // HB: bandwidth + Request.Payload[5] = blockwidthMost % 256; // LB: bandwidth + Request.Payload[6] = connectionLabel / 256; // HB: ConnectionLabel + Request.Payload[7] = connectionLabel % 256; // LB: ConnectionLabel + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + uint16_t conHandle = 0xFFFF; + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 4; + if (success) + conHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + + if (success && SCM_OUT == epDir && Response.PayloadLen >= 4) + connectionLabel = ( Response.Payload[2] << 8 ) | Response.Payload[3]; + + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateMostSocketV3(device, success, + Request.TargetAddress, epType, epDir, blockwidthMost, connectionLabel, conHandle, tag); + } +}; + +class CV3_ConnectSockets : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint16_t nodeAddress; + EPDataType_t epType; + uint16_t inHandle; + uint16_t outHandle; + uint16_t offset; + uint32_t tag; +public: + CV3_ConnectSockets(CNetworkDevice *d, uint16_t nodeAddress, EPDataType_t ep, uint16_t iH, + uint16_t oH, uint16_t o, uint32_t t) : device(d), epType(ep), inHandle(iH), + outHandle(oH), offset(o), tag(t) + { + ElementName = "CV3_ConnectSockets"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + + switch( epType ) + { + case EP_Isochron: + Request.Func = 0x861; //AVPCreate + Request.PayloadLen = 6; + Request.Payload[0] = inHandle / 256; // HB: in handle (will be filled by decomposerHandleIn) + Request.Payload[1] = inHandle % 256; // LB: in handle (will be filled by decomposerHandleIn) + Request.Payload[2] = outHandle / 256; // HB: out handle (will be filled by decomposerHandleOut) + Request.Payload[3] = outHandle % 256; // LB: out handle (will be filled by decomposerHandleOut) + Request.Payload[4] = 0x00; // HB: IsoPacketSize + Request.Payload[5] = 188; // LB: IsoPacketSize + break; + case EP_Synchron: + Request.Func = 0x871; // SyncCreate + Request.PayloadLen = 8; + Request.Payload[0] = inHandle / 256; // HB: in handle (will be filled by decomposerHandleIn) + Request.Payload[1] = inHandle % 256; // LB: in handle (will be filled by decomposerHandleIn) + Request.Payload[2] = outHandle / 256; // HB: out handle (will be filled by decomposerHandleOut) + Request.Payload[3] = outHandle % 256; // LB: out handle (will be filled by decomposerHandleOut) + Request.Payload[4] = 0x00; // 0: not muted by default; 1: muted by default + Request.Payload[5] = 0x00; // 0: NoMuting, 1:MuteSignal, 2:AutoMute + Request.Payload[6] = offset / 256; // HB: Offset + Request.Payload[7] = offset % 256; // LB: Offset + break; + default: + WaitForResponse = false; + ConsolePrintf( PRIO_ERROR, RED"CV3_ConnectSockets: Unsupported Data type"RESETCOLOR"\n" ); + return; + } + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + assert(this == element); + uint16_t conHandle = 0xFFFF; + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (success) + conHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnConnectSocketsV3(device, success, + Request.TargetAddress, epType, inHandle, outHandle, conHandle, tag); + } +}; + +class CV3_ResourceDestroy : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint16_t nodeAddress; + uint8_t amountOfHandles; + uint32_t tag; +public: + CV3_ResourceDestroy(CNetworkDevice *d, int16_t nodeAddress, + uint8_t amount, const uint16_t *pHandle, uint32_t t) : device(d), + amountOfHandles(amount), tag(t) + { + ElementName = "CV3_ResourceDestroy"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x800; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + + uint8_t index = 0; + Request.Payload[index++] = 0x00; // HB: SenderHandle + Request.Payload[index++] = 0x00; // LB: SenderHandle + for( uint8_t i = 0; i < amountOfHandles; i++ ) + { + Request.Payload[index++] = pHandle[i] / 256; // HB: handle + Request.Payload[index++] = pHandle[i] % 256; // LB: handle + } + Request.PayloadLen = index; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnResourceDestroyV3(device, true, + Request.TargetAddress, amountOfHandles, ( uint16_t * )&Request.Payload[2], tag); + } +}; + +class CV3_StreamPortConfig : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint8_t portInstance; + V3I2SPortOption_t option; + V3I2SClockMode_t mode; + V3I2SDelayMode_t delay; + uint32_t tag; +public: + CV3_StreamPortConfig(CNetworkDevice *d, uint16_t nodeAddress, uint8_t port, + V3I2SPortOption_t opt, V3I2SClockMode_t md, V3I2SDelayMode_t del, uint32_t t) + : device(d), portInstance(port), option(opt), mode(md), delay(del), tag(t) + { + ElementName = "CV3_StreamPortConfig"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x680; + Request.Inst = 0x00; + Request.OpType = CISOpType_SETGET; + Request.PayloadLen = 5; + Request.Payload[0] = portInstance; + Request.Payload[1] = 0x00; //Fixed operation mode 0 = Generic + Request.Payload[2] = option; + Request.Payload[3] = mode; + Request.Payload[4] = delay; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnConfigureI2SPortV3(device, (ISReturn_Success == result), + Request.TargetAddress, portInstance, option, mode, delay, tag); + } +}; + +class CV3_StreamPortCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint8_t portInstance; + V3I2SPortSpeed_t clock; + V3I2SAlignment_t align; + uint32_t tag; +public: + CV3_StreamPortCreate(CNetworkDevice *d, uint16_t nodeAddress, uint8_t port, + V3I2SPortSpeed_t cl, V3I2SAlignment_t al, uint32_t t) + : device(d), portInstance(port), clock(cl), align(al), tag(t) + { + ElementName = "CV3_StreamPortCreate"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x681; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 3; + Request.Payload[0] = portInstance; + Request.Payload[1] = clock; + Request.Payload[2] = align; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateI2SPortV3(device, (ISReturn_Success == result), + Request.TargetAddress, portInstance, clock, align, tag); + } +}; + +class CV3_StreamSocketCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint8_t portInstance; + EPDirection_t epDir; + uint16_t blockWidthI2S; + V3I2SPin_t pin; + uint32_t tag; +public: + CV3_StreamSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, uint8_t pi, EPDirection_t epd, + uint16_t bw, V3I2SPin_t p, uint32_t t) : device(d), portInstance(pi), + epDir(epd), blockWidthI2S(bw), pin(p), tag(t) + { + ElementName = "CV3_StreamSocketCreate"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x691; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 7; + Request.Payload[0] = 0x16; //Fixed port handle for I2S + Request.Payload[1] = portInstance; //dynamic port handle for I2S (Port A or B) + Request.Payload[2] = epDir; + Request.Payload[3] = 0x00; //Data type (fixed 0 for sync) + Request.Payload[4] = blockWidthI2S / 256; + Request.Payload[5] = blockWidthI2S % 256; + Request.Payload[6] = pin; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + uint16_t i2sHandle = 0xFFFF; + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (success) + i2sHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateI2SSocketV3(device, success, + Request.TargetAddress, portInstance, epDir, blockWidthI2S, pin, i2sHandle, tag); + } +}; + +class CV3_SplittedStreamSocketCreate : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint8_t portInstance; + EPDirection_t epDir; + uint16_t blockWidthI2S; + V3I2SPin_t pin; + uint16_t bytesPerPacket; + uint32_t tag; + uint16_t i2sHandle; +public: + CV3_SplittedStreamSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, uint8_t pi, + EPDirection_t epd, uint16_t bw, V3I2SPin_t p, uint16_t bp, uint32_t t) : device(d), + portInstance(pi), epDir(epd), blockWidthI2S(bw), pin(p), bytesPerPacket(bp), tag(t), + i2sHandle(0xFFFF) + { + ElementName = "CV3_SplittedStreamSocketCreate-Stream"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x691; + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 7; + Request.Payload[0] = 0x16; //Fixed port handle for I2S + Request.Payload[1] = portInstance; //dynamic port handle for I2S (Port A or B) + Request.Payload[2] = epDir; + Request.Payload[3] = 0x00; //Data type (fixed 0 for sync) + Request.Payload[4] = blockWidthI2S / 256; + Request.Payload[5] = blockWidthI2S % 256; + Request.Payload[6] = pin; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 2; + if (!success) + { + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateSplittedI2SSocketV3(device, false, + Request.TargetAddress, portInstance, epDir, blockWidthI2S, pin, + 0xFFFF, 0xFFFF, tag); + return; + } + if (0x691 == Response.Func) + { + i2sHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + CreateSplitter(iStack); + } + else + { + uint16_t splitterHandle = ( Response.Payload[0] << 8 ) | Response.Payload[1]; + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnCreateSplittedI2SSocketV3(device, success, + Request.TargetAddress, portInstance, epDir, blockWidthI2S, pin, + i2sHandle, splitterHandle, tag); + } + } +private: + void CreateSplitter(CIndustrialStack *iStack) + { + assert(i2sHandle != 0xFFFF); + ElementName = "CV3_SplittedStreamSocketCreate-Splitter"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_RESULT; + Callback = this; + startTime = 0; + Request.FBlock = 0x0; + if( EPDIR_IN == epDir ) + Request.Func = 0x911; //SplitterCreate + else + Request.Func = 0x901; //CombinerCreate + Request.Inst = 0x00; + Request.OpType = CISOpType_STARTRESULT; + Request.PayloadLen = 6; + Request.Payload[0] = i2sHandle / 256; // HB: SocketHandle IN/OUT + Request.Payload[1] = i2sHandle % 256; // LB: SocketHandle IN/OUT + Request.Payload[2] = 0x0D; // HB: MOSTPortHandle + Request.Payload[3] = 0x00; // LB: MOSTPortHandle + Request.Payload[4] = bytesPerPacket / 256; // HB: BytesPerFrame + Request.Payload[5] = bytesPerPacket % 256; // LB: BytesPerFrame + iStack->EnqueueElement(Request.TargetAddress, this); + } +}; + +class CV3_GetRbdResult : public CISSendMostMsgElement +{ +public: + CV3_GetRbdResult(uint16_t nodeAddress) + { + ElementName = "CV3_GetRbdResult"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_STATUS; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Func = 0x527; + Request.Inst = 0x00; + Request.OpType = CISOpType_GET; + Request.PayloadLen = 0; + } +}; + +class CV3_DeviceVersion : public CISSendMostMsgElement, public IISElementCallback +{ +private: + CNetworkDevice *device; + uint16_t nodeAddress; + EPDataType_t epType; + uint16_t inHandle; + uint16_t outHandle; + uint16_t offset; + uint32_t tag; +public: + CV3_DeviceVersion(CNetworkDevice *d, uint16_t nodeAddress, uint32_t t) : device(d), tag(t) + { + ElementName = "CV3_DeviceVersion"; + WaitForResponse = true; + WaitForResponseOpType = CISOpType_STATUS; + Callback = this; + + Request.IsValid = true; + Request.SourceAddress = 0x2; + Request.TargetAddress = nodeAddress; + Request.FBlock = 0x0; + Request.Inst = 0x00; + Request.Func = 0x221; + Request.OpType = CISOpType_GET; + Request.PayloadLen = 0; + } + + virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) + { + assert(this == element); + bool success = (ISReturn_Success == result) && Response.PayloadLen >= 13; + + uint32_t productId = 0xFFFFFFFF; + uint32_t fwVersion = 0xFFFFFFFF; + uint32_t buildVersion = 0xFFFFFFFF; + uint8_t hwVersion = 0xFF; + uint16_t diagnosisId = 0xFFFF; + + if (success) + { + productId = ( Response.Payload[0] << 24 ) + | ( Response.Payload[1] << 16 ) + | ( Response.Payload[2] << 8 ) + | Response.Payload[3]; + + fwVersion = ( Response.Payload[4] << 24 ) + | ( Response.Payload[5] << 16 ) + | ( Response.Payload[6] << 8 ); + + buildVersion = ( Response.Payload[7] << 24 ) + | ( Response.Payload[8] << 16 ) + | ( Response.Payload[9] << 8 ) + | Response.Payload[10]; + + hwVersion = Response.Payload[10]; + + diagnosisId = ( Response.Payload[11] << 8 ) + | Response.Payload[12]; + } + + for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ ) + device->GetListener( i )->OnDeviceVersion(device, success, Response.SourceAddress, + productId, fwVersion, buildVersion, hwVersion, diagnosisId, tag); + } +}; + +#endif //INDUSTRIAL_STACK_API_V3_H
\ No newline at end of file |