/* * Video On Demand Samples * * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * You may also obtain this software under a propriety license from Microchip. * Please contact Microchip for further information. * */ /*----------------------------------------------------------*/ /*! \file * \brief This file contains the 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