summaryrefslogtreecommitdiffstats
path: root/Src/Network
diff options
context:
space:
mode:
authorChristian Gromm <christian.gromm@microchip.com>2016-12-08 13:51:04 +0100
committerChristian Gromm <christian.gromm@microchip.com>2016-12-08 13:51:04 +0100
commit8c5f2324d7aa61669324aec1a0ad091fe1379489 (patch)
tree29cbdcdbe3657e1400d596ec3d560a2573d80817 /Src/Network
parente89ba11bd9111f02a940f227cf979f1947e975ac (diff)
src: unicens: import sources
This patch adds the source tree of the NetworkManager v3.0.4. Additionally, it provides the needed configuration scripts. Change-Id: I23778b51423b51a4f87741957e0fb208bceb79b3 Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
Diffstat (limited to 'Src/Network')
-rw-r--r--Src/Network/IndustrialStack.cpp275
-rw-r--r--Src/Network/IndustrialStack.h238
-rw-r--r--Src/Network/IndustrialStack_ApiGeneric.h125
-rw-r--r--Src/Network/IndustrialStack_ApiV1.h712
-rw-r--r--Src/Network/IndustrialStack_ApiV3.h1123
-rw-r--r--Src/Network/IndustrialStack_LLD.cpp278
-rw-r--r--Src/Network/IndustrialStack_LLD.h148
-rw-r--r--Src/Network/IndustrialStack_MNS.cpp414
-rw-r--r--Src/Network/IndustrialStack_MNS.h84
-rw-r--r--Src/Network/IndustrialStack_Types.h159
-rw-r--r--Src/Network/Network.cpp433
-rw-r--r--Src/Network/Network.h498
-rw-r--r--Src/Network/NetworkDevice.cpp903
-rw-r--r--Src/Network/NetworkDevice.h862
-rw-r--r--Src/Network/NetworkDeviceListener.cpp306
-rw-r--r--Src/Network/NetworkDeviceListener.h568
-rw-r--r--Src/Network/Network_CB.cpp1823
-rw-r--r--Src/Network/Network_Private.cpp695
-rw-r--r--Src/Network/NodeDatabase.cpp287
-rw-r--r--Src/Network/NodeDatabase.h379
-rw-r--r--Src/Network/base/.svn/dir-prop-base14
-rw-r--r--Src/Network/base/.svn/entries164
-rw-r--r--Src/Network/base/.svn/prop-base/DriverConfiguration.c.svn-base5
-rw-r--r--Src/Network/base/.svn/prop-base/DriverConfiguration.h.svn-base5
-rw-r--r--Src/Network/base/.svn/text-base/Board.c.svn-base51
-rw-r--r--Src/Network/base/.svn/text-base/Board.h.svn-base63
-rw-r--r--Src/Network/base/.svn/text-base/DriverConfiguration.c.svn-base608
-rw-r--r--Src/Network/base/.svn/text-base/DriverConfiguration.h.svn-base239
-rw-r--r--Src/Network/base/Board.c51
-rw-r--r--Src/Network/base/Board.h63
-rw-r--r--Src/Network/base/DriverConfiguration.c608
-rw-r--r--Src/Network/base/DriverConfiguration.h239
32 files changed, 12420 insertions, 0 deletions
diff --git a/Src/Network/IndustrialStack.cpp b/Src/Network/IndustrialStack.cpp
new file mode 100644
index 0000000..e84ab22
--- /dev/null
+++ b/Src/Network/IndustrialStack.cpp
@@ -0,0 +1,275 @@
+/*
+ * 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.
+ */
+/*----------------------------------------------------------*/
+
+//#define CON_TRACE
+
+#define DISABLE_PARALLEL_MODE
+
+#include <assert.h>
+#include "IndustrialStack.h"
+
+CIndustrialStack::CIndustrialStack(uint8_t deviceApi, int controlRxHandle, int controlTxHandle)
+{
+ msnw = new CISNetServiceWrapper(deviceApi, controlRxHandle, controlTxHandle);
+ msnw->AddListener(this);
+ GetQueue(0x3C8); //Make sure that Broadcast queue is the first one
+}
+
+CIndustrialStack::~CIndustrialStack()
+{
+ delete msnw;
+ deviceQueues.RemoveAll(true);
+ intEventListeners.RemoveAll(false);
+}
+
+void CIndustrialStack::EnqueueElement(uint16_t nodeAddress, IISElement *element)
+{
+ CISDeviceQueue *dev = GetQueue(nodeAddress);
+ assert(NULL != dev);
+ element->AddReference();
+ dev->elements.PushBack(element);
+}
+
+void CIndustrialStack::ServiceStack(uint32_t time)
+{
+ for (uint32_t i = 0; i < deviceQueues.Size(); i++)
+ {
+ assert(NULL != deviceQueues[i]);
+ if (deviceQueues[i]->elements.Size() == 0)
+ continue;
+ IISElement *element = deviceQueues[i]->elements[0];
+ assert(NULL != element);
+ ISReturn_t state = element->Service(this, time);
+ if (state == ISReturn_NoChange)
+ continue;
+ deviceQueues[i]->elements.PopFront();
+ HandleStateChange(state, element);
+ element->RemoveReference();
+ msnw->ServiceMns();
+ }
+ msnw->ServiceMns();
+}
+
+bool CIndustrialStack::ElementsPending()
+{
+ for (uint32_t i = 0; i < deviceQueues.Size(); i++)
+ {
+ assert(NULL != deviceQueues[i]);
+ if (deviceQueues[i]->elements.Size() != 0)
+ return true;
+ }
+ return false;
+}
+
+bool CIndustrialStack::ElementsPending(uint16_t ingoreNodeAddress)
+{
+ for (uint32_t i = 0; i < deviceQueues.Size(); i++)
+ {
+ CISDeviceQueue *q = deviceQueues[i];
+ assert(NULL != q);
+ if (q->GetNodeAddress() == ingoreNodeAddress)
+ continue;
+ if (q->elements.Size() != 0)
+ return true;
+ }
+ return false;
+}
+
+void CIndustrialStack::ClearAllElements()
+{
+ for (uint32_t i = 0; i < deviceQueues.Size(); i++)
+ {
+ assert(NULL != deviceQueues[i]);
+ deviceQueues[i]->elements.RemoveAll(true);
+ }
+}
+
+bool CIndustrialStack::SendMostMessage(CISMostMsg *message)
+{
+ assert(NULL != msnw);
+ assert(NULL != message);
+ if (NULL == message)
+ return false;
+#ifdef CON_TRACE
+ ConsolePrintfStart(PRIO_HIGH, "IS TX, node:0x%X," \
+ " fblock:0x%X, func:0x%X, op:0x%X pl:0x[", message->TargetAddress,
+ message->FBlock, message->Func, message->OpType);
+ for (uint32_t i = 0; i < message->PayloadLen; i++)
+ ConsolePrintfContinue(" %02X", message->Payload[i]);
+ ConsolePrintfExit(" ]\n");
+#endif
+ bool success = msnw->SendMostMessage(message);
+ for (uint32_t i = 0; success && i < intEventListeners.Size(); i++)
+ {
+ intEventListeners[i]->OnMostMessage(this, message);
+ }
+ return success;
+}
+
+void CIndustrialStack::Unsynchronize()
+{
+ assert(NULL != msnw);
+ return msnw->Unsynchronize();
+}
+
+void CIndustrialStack::AddInternalEventListener(CSInternalEvent* callback)
+{
+ intEventListeners.PushBack(callback);
+}
+
+/*--------------------------
+ * Callback from MSN Wrapper
+ *--------------------------
+ */
+
+void CIndustrialStack::OnReceivedMostMessage(CISMostMsg *rcvMessage)
+{
+ assert(NULL != rcvMessage);
+ assert(rcvMessage->IsValid);
+#ifdef CON_TRACE
+ ConsolePrintfStart(PRIO_HIGH, "IS RX, node:0x%X," \
+ " fblock:0x%X, func:0x%X, op:0x%X pl:0x[", rcvMessage->SourceAddress,
+ rcvMessage->FBlock, rcvMessage->Func, rcvMessage->OpType);
+ for (uint32_t i = 0; i < rcvMessage->PayloadLen; i++)
+ ConsolePrintfContinue(" %02X", rcvMessage->Payload[i]);
+ ConsolePrintfExit(" ]\n");
+#endif
+ if (CISOpType_ERROR == rcvMessage->OpType
+ || CISOpType_ERRORACK == rcvMessage->OpType)
+ {
+ //Ignore Destroy Resource Errors
+ if (rcvMessage->Func != 0x800)
+ {
+ ConsolePrintfStart(PRIO_ERROR, RED"Received error message, node:0x%X," \
+ " fblock:0x%X, func:0x%X, op:0x%X pl:0x[", rcvMessage->SourceAddress,
+ rcvMessage->FBlock, rcvMessage->Func, rcvMessage->OpType);
+ for (uint32_t i = 0; i < rcvMessage->PayloadLen; i++)
+ ConsolePrintfContinue(" %02X", rcvMessage->Payload[i]);
+ ConsolePrintfExit(" ]"RESETCOLOR"\n");
+ }
+ }
+ for (uint32_t i = 0; i < deviceQueues.Size(); i++)
+ {
+ assert(NULL != deviceQueues[i]);
+ IISElement *element = deviceQueues[i]->elements[0];
+ if (NULL == element)
+ continue;
+ ISReturn_t state = element->OnMostMessage(this, rcvMessage);
+ if (state == ISReturn_NoChange)
+ continue;
+ deviceQueues[i]->elements.PopFront();
+ HandleStateChange(state, element);
+ element->RemoveReference();
+ }
+ for (uint32_t i = 0; i < intEventListeners.Size(); i++)
+ {
+ intEventListeners[i]->OnMostMessage(this, rcvMessage);
+ }
+}
+
+void CIndustrialStack::OnSyncStateChanged(bool isSynced)
+{
+ for (uint32_t i = 0; i < intEventListeners.Size(); i++)
+ {
+ assert(NULL != intEventListeners[i]);
+ intEventListeners[i]->OnSyncStateChanged(this, isSynced);
+ }
+}
+
+void CIndustrialStack::OnControlReadEnd()
+{
+ for (uint32_t i = 0; i < intEventListeners.Size(); i++)
+ {
+ assert(NULL != intEventListeners[i]);
+ intEventListeners[i]->OnControlReadEnd(this);
+ }
+}
+
+/*--------------------------
+ * Private helper functions:
+ *--------------------------
+ */
+
+#ifdef DISABLE_PARALLEL_MODE
+CISDeviceQueue *CIndustrialStack::GetQueue(uint16_t nodeAddress)
+{
+ CISDeviceQueue *dev = deviceQueues[0];
+ if (NULL == dev)
+ {
+ ConsolePrintf(PRIO_HIGH, GREEN"Creating new Device Queue"RESETCOLOR"\n");
+ dev = new CISDeviceQueue(0);
+ deviceQueues.PushBack(dev);
+ }
+ return dev;
+}
+#else
+CISDeviceQueue *CIndustrialStack::GetQueue(uint16_t nodeAddress)
+{
+ CISDeviceQueue *dev = NULL;
+ if (nodeAddress >= 0x400 && nodeAddress <= 0x4FF)
+ nodeAddress -= 0x300;
+ for (uint32_t i = 0; i < deviceQueues.Size(); i++)
+ {
+ if (deviceQueues[i]->GetNodeAddress() == nodeAddress)
+ {
+ dev = deviceQueues[i];
+ break;
+ }
+ }
+ if (NULL == dev)
+ {
+ ConsolePrintf(PRIO_HIGH, GREEN"Creating new Device Queue for"\
+ " node address:0x%02X"RESETCOLOR"\n", nodeAddress);
+ dev = new CISDeviceQueue(nodeAddress);
+ deviceQueues.PushBack(dev);
+ }
+ return dev;
+}
+#endif
+
+void CIndustrialStack::HandleStateChange(ISReturn_t state, IISElement * element)
+{
+ assert(NULL != element);
+ switch (state)
+ {
+ case ISReturn_Failure:
+ case ISReturn_Timeout:
+ ConsolePrintf(PRIO_ERROR, RED"Job '%s' %s"RESETCOLOR"\n",
+ element->ElementName, state == ISReturn_Failure ? "failed" : "timed out");
+ case ISReturn_Success:
+ if (NULL != element->Callback)
+ element->Callback->ElementProcessed(this, state, element);
+ break;
+ case ISReturn_NoChange:
+ //Nothing to do
+ break;
+ default:
+ assert(false);
+ }
+}
diff --git a/Src/Network/IndustrialStack.h b/Src/Network/IndustrialStack.h
new file mode 100644
index 0000000..fc42f66
--- /dev/null
+++ b/Src/Network/IndustrialStack.h
@@ -0,0 +1,238 @@
+/*
+ * 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 (common part).
+ */
+/*----------------------------------------------------------*/
+
+#ifndef INDUSTRIAL_STACK_H
+#define INDUSTRIAL_STACK_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include "SafeVector.h"
+#include "IndustrialStack_Types.h"
+#include "IndustrialStack_MNS.h"
+#include "Console.h"
+
+class CIndustrialStack : IISNetServiceWrapperCB
+{
+private:
+ CISNetServiceWrapper *msnw;
+ CSafeVector<CISDeviceQueue *> deviceQueues;
+ CSafeVector<CSInternalEvent *> intEventListeners;
+ CISDeviceQueue *GetQueue(uint16_t deviceType);
+ void HandleStateChange(ISReturn_t state, IISElement * element);
+public:
+ CIndustrialStack(uint8_t deviceApi, int controlRxHandle, int controlTxHandle);
+ virtual ~CIndustrialStack();
+ void ServiceStack(uint32_t time);
+ void EnqueueElement(uint16_t nodeAddress, IISElement *element);
+ bool ElementsPending();
+ bool ElementsPending(uint16_t ingoreNodeAddress);
+ void ClearAllElements();
+ bool SendMostMessage(CISMostMsg *message);
+ void Unsynchronize();
+ void AddInternalEventListener(CSInternalEvent* callback);
+
+ /* Callback from IISNetServiceWrapperCB interface */
+ virtual void OnReceivedMostMessage(CISMostMsg *rcvMessage);
+ virtual void OnSyncStateChanged(bool isSynced);
+ virtual void OnControlReadEnd();
+};
+
+class CISWaitElement : public IISElement
+{
+protected:
+ uint32_t startTime;
+ uint32_t timeout;
+public:
+ CISWaitElement() : IISElement(), startTime(0), timeout(2000)
+ {
+ ElementName = "Wait Element";
+ }
+
+ void SetTimeout(uint32_t timeInMillis)
+ {
+ timeout = timeInMillis;
+ }
+
+ virtual ISReturn_t Service(CIndustrialStack *iStack, uint32_t time)
+ {
+ assert(NULL != iStack);
+ if (0 == startTime)
+ startTime = time;
+ else if ( ( time - startTime >= timeout ) )
+ return ISReturn_Success;
+ return ISReturn_NoChange;
+ }
+
+ virtual ISReturn_t OnMostMessage(CIndustrialStack *iStack, CISMostMsg *rcvMessage)
+ {
+ assert(NULL != iStack);
+ return ISReturn_NoChange;
+ }
+};
+
+class CISWaitForPendingElements : public CISWaitElement
+{
+private:
+ uint16_t ignoreNode;
+public:
+ CISWaitForPendingElements(uint16_t ingoreNodeAddress)
+ : CISWaitElement(), ignoreNode(ingoreNodeAddress)
+ {
+ }
+
+ virtual ISReturn_t Service(CIndustrialStack *iStack, uint32_t time)
+ {
+ assert(NULL != iStack);
+ if (!iStack->ElementsPending(ignoreNode))
+ return ISReturn_Success;
+ return (CISWaitElement::Service(iStack, time) == ISReturn_NoChange)
+ ? ISReturn_NoChange : ISReturn_Timeout;
+ }
+};
+
+class CISSendMostMsgElement : public CISWaitElement
+{
+private:
+ uint8_t retryCount;
+public:
+ CISMostMsg Request;
+ CISMostMsg Response;
+ bool WaitForResponse;
+ CISOpType_t WaitForResponseOpType;
+
+ CISSendMostMsgElement() : CISWaitElement(), retryCount(4),
+ WaitForResponse(false),
+ WaitForResponseOpType(CISOpType_INVALID)
+ {
+ timeout = 500;
+ }
+
+ virtual ISReturn_t Service(CIndustrialStack *iStack, uint32_t time)
+ {
+ assert(NULL != iStack);
+ if (0 == startTime)
+ {
+ CISWaitElement::Service(iStack, time);
+ if (Request.IsValid == false || Request.FBlock == 0xFFFFFFFF
+ || Request.Func == 0xFFFFFFFF || Request.Inst == 0xFFFFFFFF
+ || Request.OpType == CISOpType_INVALID)
+ {
+ ConsolePrintf(PRIO_ERROR,
+ RED"CISSendMostMsgElement %s invalid MOST message to be"\
+ " sent"RESETCOLOR"\n", ElementName);
+ return ISReturn_Failure;
+ }
+ bool success = iStack->SendMostMessage(&Request);
+ if (success && !WaitForResponse)
+ return ISReturn_Success;
+ return success ? ISReturn_NoChange : ISReturn_Failure;
+ }
+ ISReturn_t waitState = CISWaitElement::Service(iStack, time);
+ if (ISReturn_Success == waitState)
+ {
+ if (0 == --retryCount)
+ {
+ ConsolePrintf(PRIO_ERROR, RED"All High level retries failed for Request '%s',"\
+ " node 0x%X!"RESETCOLOR"\n",
+ ElementName, Request.TargetAddress);
+ return ISReturn_Timeout;
+ }
+ //Retry sending
+ ConsolePrintf(PRIO_HIGH, YELLOW"High level retry after timeout for Request '%s',"\
+ " node 0x%X"RESETCOLOR"\n",
+ ElementName, Request.TargetAddress);
+ startTime = time;
+ return (iStack->SendMostMessage(&Request)) ? ISReturn_NoChange : ISReturn_Failure;
+ }
+ return ISReturn_NoChange;
+ }
+
+ virtual ISReturn_t OnMostMessage(CIndustrialStack *iStack, CISMostMsg *rcvMessage)
+ {
+ if (!WaitForResponse)
+ return ISReturn_NoChange;
+ assert(NULL != iStack);
+ assert(NULL != rcvMessage);
+ assert(Request.IsValid);
+ assert(rcvMessage->IsValid);
+
+ uint32_t requestAddr = Request.TargetAddress;
+ uint32_t responseAddr = rcvMessage->SourceAddress;
+ if (requestAddr >= 0x400 && requestAddr <= 0x4FF )
+ requestAddr -= 0x300;
+ if (responseAddr >= 0x400 && responseAddr <= 0x4FF )
+ responseAddr -= 0x300;
+
+ if ( ( requestAddr < 0x300 || requestAddr > 0x3FF )
+ && ( responseAddr != requestAddr))
+ return ISReturn_NoChange;
+
+ if ( rcvMessage->FBlock == Request.FBlock
+ && rcvMessage->Func == Request.Func)
+ {
+ if (rcvMessage->OpType == WaitForResponseOpType)
+ {
+ Response.DeepCopy(rcvMessage);
+ return ISReturn_Success;
+ }
+ else if(0 == --retryCount)
+ {
+ Response.DeepCopy(rcvMessage);
+ return ISReturn_Failure;
+ }
+ //Retry sending
+ ConsolePrintf(PRIO_HIGH, YELLOW"High level retry after wrong result for Request '%s',"\
+ " node 0x%X"RESETCOLOR"\n",
+ ElementName, Request.TargetAddress);
+ return (iStack->SendMostMessage(&Request)) ? ISReturn_NoChange : ISReturn_Failure;
+ }
+ return ISReturn_NoChange;
+ }
+};
+
+class CSInternalEvent : public IISElement
+{
+public:
+ virtual ISReturn_t Service(CIndustrialStack *iStack, uint32_t time)
+ {
+ //Must not be called
+ return ISReturn_Failure;
+ }
+ virtual ISReturn_t OnMostMessage(CIndustrialStack *iStack, CISMostMsg *r)
+ {
+ //Must not be called
+ return ISReturn_Failure;
+ }
+ virtual void OnSyncStateChanged(CIndustrialStack *iStack, bool isSynced) {}
+ virtual void OnControlReadEnd(CIndustrialStack *iStack) {}
+};
+
+#endif //INDUSTRIAL_STACK_H
diff --git a/Src/Network/IndustrialStack_ApiGeneric.h b/Src/Network/IndustrialStack_ApiGeneric.h
new file mode 100644
index 0000000..730f157
--- /dev/null
+++ b/Src/Network/IndustrialStack_ApiGeneric.h
@@ -0,0 +1,125 @@
+/*
+ * 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 (Generic commands).
+ */
+/*----------------------------------------------------------*/
+
+#ifndef INDUSTRIAL_STACK_API_GENERIC_H
+#define INDUSTRIAL_STACK_API_GENERIC_H
+
+#include "IndustrialStack.h"
+#include "Network.h"
+#include "Types.h"
+
+class CGeneric_SendConfigOk : public CISSendMostMsgElement
+{
+public:
+ CGeneric_SendConfigOk(bool isOkay)
+ {
+ ElementName = "CGeneric_SendConfigOk";
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = 0x3C8;
+ Request.FBlock = 0x2;
+ Request.Func = 0xA00;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STATUS;
+ Request.PayloadLen = 1;
+ Request.Payload[0] = isOkay;
+ }
+};
+
+class CGeneric_GetMacAddress : public CISSendMostMsgElement
+{
+public:
+ CGeneric_GetMacAddress(uint16_t nodeAddress)
+ {
+ ElementName = "CGeneric_GetMacAddress";
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x1;
+ Request.Func = 0x013;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_GET;
+ Request.PayloadLen = 0;
+ }
+};
+
+class CGeneric_GetGroupAddress : public CISSendMostMsgElement
+{
+public:
+ CGeneric_GetGroupAddress(uint16_t nodeAddress)
+ {
+ ElementName = "CGeneric_GetGroupAddress";
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x1;
+ Request.Func = 0x004;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_GET;
+ Request.PayloadLen = 0;
+ }
+};
+
+class CGeneric_SendMostMessage : public CISSendMostMsgElement
+{
+public:
+ CGeneric_SendMostMessage(const uint8_t *pPayload, uint32_t payloadLength,
+ uint16_t nodeAddress, uint8_t fblockId, uint8_t instanceId,
+ uint16_t functionId, uint8_t opTypeRequest, uint8_t opTypeResponse)
+ {
+ if (payloadLength > sizeof(Request.Payload))
+ {
+ ConsolePrintf(PRIO_ERROR, RED"CGeneric_SendMostMessage was called"\
+ " with to big payload size"RESETCOLOR"\n");
+ payloadLength = sizeof(Request.Payload);
+ }
+ ElementName = "CGeneric_SendMostMessage";
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = fblockId;
+ Request.Func = functionId;
+ Request.Inst = instanceId;
+ Request.OpType = (CISOpType_t)opTypeRequest;
+ Request.PayloadLen = payloadLength;
+ if (0 != payloadLength)
+ memcpy(Request.Payload, pPayload, payloadLength);
+ if( 0xFF != opTypeResponse )
+ {
+ WaitForResponse = true;
+ WaitForResponseOpType = (CISOpType_t)opTypeResponse;
+ }
+ }
+};
+
+#endif //INDUSTRIAL_STACK_API_GENERIC_H
diff --git a/Src/Network/IndustrialStack_ApiV1.h b/Src/Network/IndustrialStack_ApiV1.h
new file mode 100644
index 0000000..1c7f45a
--- /dev/null
+++ b/Src/Network/IndustrialStack_ApiV1.h
@@ -0,0 +1,712 @@
+/*
+ * 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 V1 commands).
+ */
+/*----------------------------------------------------------*/
+
+#ifndef INDUSTRIAL_STACK_API_V1_H
+#define INDUSTRIAL_STACK_API_V1_H
+
+#define ISO_PACKET_SIZE 188
+
+#include "IndustrialStack.h"
+#include "Network.h"
+#include "Types.h"
+
+class CV1_OnMostRx : public CSInternalEvent
+{
+private:
+ CNetworkDevice *device;
+public:
+ CV1_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 0x30E: //Change 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 OnControlReadEnd(CIndustrialStack *iStack)
+ {
+ assert(NULL != device);
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnControlChannelReadEnd(device);
+ }
+};
+
+class CV1_ChangeEUI48 : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+public:
+ CV1_ChangeEUI48(CNetworkDevice *d, uint16_t nodeAddress,
+ uint8_t macAddress1, uint8_t macAddress2, uint8_t macAddress3,
+ uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6,
+ bool persistent) : device(d)
+ {
+ ElementName = "CV1_ChangeEUI48";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x30E;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 7;
+ Request.Payload[0] = macAddress1;
+ Request.Payload[1] = macAddress2;
+ Request.Payload[2] = macAddress3;
+ Request.Payload[3] = macAddress4;
+ Request.Payload[4] = macAddress5;
+ Request.Payload[5] = macAddress6;
+ Request.Payload[6] = persistent;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ assert(this == element);
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 6;
+ if (success)
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnMostMacAddress(device, true,
+ Request.TargetAddress, Response.Payload[0],Response.Payload[1],
+ Response.Payload[2], Response.Payload[3], Response.Payload[4],
+ Response.Payload[5]);
+ 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 CV1_NetworkStartup : public CISWaitElement
+{
+private:
+ CNetworkDevice *device;
+public:
+ CV1_NetworkStartup(CNetworkDevice *d, bool isTimingMaster, uint16_t packetBW) : device(d)
+ {
+ ElementName = "CV1_NetworkStartup is not implemented!";
+ timeout = 1;
+ }
+};
+
+class CV1_NetworkShutdown : public CISWaitElement
+{
+private:
+ CNetworkDevice *device;
+public:
+ CV1_NetworkShutdown(CNetworkDevice *d) : device(d)
+ {
+ ElementName = "CV1_NetworkShutdown is not implemented!";
+ timeout = 1;
+ }
+};
+
+class CV1_TsiPortCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+public:
+ CV1_TsiPortCreate(CNetworkDevice *d, uint16_t nodeAddress, V1TsiPortInstance_t tsiPort, V1TsiPortMode tsiMode) : device(d)
+ {
+ ElementName = "CV2_TsiPortCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x400;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 2;
+ Request.Payload[0] = tsiPort;
+ Request.Payload[1] = tsiMode;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnOpenTsiV1(device, (ISReturn_Success == result), Request.TargetAddress);
+ }
+};
+
+class CV1_TsiSocketCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ V1TsiPortInstance_t tsiPort;
+ EPDataType_t epType;
+ EPDirection_t epDir;
+ uint16_t blockWidthTsi;
+ uint32_t tag;
+public:
+ CV1_TsiSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, V1TsiPortInstance_t tp,
+ EPDataType_t ept, EPDirection_t epd, uint16_t bw, uint32_t t) :
+ device(d), tsiPort(tp), epType(ept), epDir(epd), blockWidthTsi(bw), tag(t)
+ {
+ if ( EP_Isochron != epType )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"CV1_TsiSocketCreate: Unsupported Data type"RESETCOLOR"\n" );
+ return;
+ }
+ ElementName = "CV1_TsiSocketCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x403;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 7;
+ Request.Payload[0] = tsiPort;
+ Request.Payload[1] = epDir;
+ Request.Payload[2] = epType;
+ Request.Payload[3] = blockWidthTsi / 256;
+ Request.Payload[4] = blockWidthTsi % 256;
+ Request.Payload[5] = ISO_PACKET_SIZE / 256;
+ Request.Payload[6] = ISO_PACKET_SIZE % 256;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ uint8_t tsiPortHandle = 0xFF;
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 1;
+ if (success)
+ tsiPortHandle = Response.Payload[0];
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnCreateTsiSocketV1(device, success, Request.TargetAddress, tsiPort,
+ epType, epDir, blockWidthTsi, tsiPortHandle, tag);
+ }
+};
+
+class CV1_MlbPortCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+public:
+ CV1_MlbPortCreate(CNetworkDevice *d, uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed) : device(d)
+ {
+ ElementName = "CV2_MlbPortCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x400;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 4;
+ Request.Payload[0] = 0x00; //SCM_PORT_ID_MEDIALB;
+ Request.Payload[1] = 0xFF;
+ Request.Payload[2] = 0x00; //SCM_PORT_CFG_MLB_MODE_CTL;
+ Request.Payload[3] = mlbSpeed;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnOpenMlbV1(device, (ISReturn_Success == result), Request.TargetAddress);
+ }
+};
+
+class CV1_MlbSocketCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ EPDataType_t epType;
+ EPDirection_t epDir;
+ uint16_t mlbChannelAddress;
+ uint16_t blockWidthMlb;
+ uint32_t tag;
+public:
+ CV1_MlbSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, EPDataType_t ept, EPDirection_t epd,
+ uint16_t mlb, uint16_t bw, uint32_t t) : device(d), epType(ept), epDir(epd),
+ mlbChannelAddress(mlb), blockWidthMlb(bw), tag(t)
+ {
+ ElementName = "CV1_MlbSocketCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x403;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 7;
+ Request.Payload[0] = 0x00; //SCM_PORT_ID_MEDIALB
+ Request.Payload[1] = epDir;
+ Request.Payload[2] = epType;
+ Request.Payload[3] = blockWidthMlb / 256;
+ Request.Payload[4] = blockWidthMlb % 256;
+ Request.Payload[5] = mlbChannelAddress / 256;
+ Request.Payload[6] = mlbChannelAddress % 256;
+ if ( EP_Isochron == epType )
+ {
+ Request.PayloadLen = 10;
+ Request.Payload[7] = ISO_PACKET_SIZE / 256;
+ Request.Payload[8] = ISO_PACKET_SIZE % 256;
+ Request.Payload[9] = 0x1; //SCM_FLOW_CONTROL_ON
+ }
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ uint8_t mlbPortHandle = 0xFF;
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 1;
+ if (success)
+ mlbPortHandle = Response.Payload[0];
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnCreateMlbSocketV1(device, success, Request.TargetAddress, epType,
+ epDir, blockWidthMlb, mlbChannelAddress, mlbPortHandle, tag);
+ }
+};
+
+class CV1_SplittedMlbSocketCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ EPDataType_t epType;
+ EPDirection_t epDir;
+ uint16_t mlbChannelAddress;
+ uint16_t blockWidthMlb;
+ uint16_t splittedOffset;
+ uint16_t blockWidthCombined;
+ uint32_t tag;
+public:
+ CV1_SplittedMlbSocketCreate(CNetworkDevice *d, uint16_t nodeAddress,
+ EPDataType_t ept, EPDirection_t epd, uint16_t mlb, uint16_t bw,
+ uint16_t so, uint16_t bwc, uint32_t t)
+ : device(d), epType(ept), epDir(epd), mlbChannelAddress(mlb),
+ blockWidthMlb(bw), splittedOffset(so), blockWidthCombined(bwc), tag(t)
+ {
+ ElementName = "CV1_SplittedMlbSocketCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x403;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 9;
+ Request.Payload[0] = 0x00; //SCM_PORT_ID_MEDIALB
+ Request.Payload[1] = epDir;
+ Request.Payload[2] = epType;
+ Request.Payload[3] = blockWidthMlb / 256;
+ Request.Payload[4] = blockWidthMlb % 256;
+ Request.Payload[5] = mlbChannelAddress / 256;
+ Request.Payload[6] = mlbChannelAddress % 256;
+ Request.Payload[7] = ( uint8_t )( splittedOffset & 0xFF );
+ Request.Payload[8] = ( uint8_t )( blockWidthCombined & 0xFF );
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ uint8_t mlbPortHandle = 0xFF;
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 1;
+ if (success)
+ mlbPortHandle = Response.Payload[0];
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnCreateMlbSocketV1(device, success, Request.TargetAddress, epType,
+ epDir, blockWidthMlb, mlbChannelAddress, mlbPortHandle, tag);
+ }
+};
+
+class CV1_MostSocketCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ EPDataType_t epType;
+ EPDirection_t epDir;
+ uint16_t connectionLabel;
+ uint16_t blockWidthMost;
+ uint32_t tag;
+public:
+ CV1_MostSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, EPDataType_t ept, EPDirection_t epd,
+ uint16_t cl, uint16_t bw, uint32_t t) : device(d), epType(ept), epDir(epd),
+ connectionLabel(cl), blockWidthMost(bw), tag(t)
+ {
+ ElementName = "CV1_MostSocketCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x403;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.Payload[0] = 0x02; //SCM_PORT_ID_MOST
+ Request.Payload[1] = epDir;
+ Request.Payload[2] = epType;
+ Request.Payload[3] = blockWidthMost / 256;
+ Request.Payload[4] = blockWidthMost % 256;
+ switch( epType )
+ {
+ case EP_Isochron:
+ Request.Payload[5] = ISO_PACKET_SIZE / 256;
+ Request.Payload[6] = ISO_PACKET_SIZE % 256;
+ if( SCM_IN == epDir )
+ {
+ Request.PayloadLen = 10;
+ Request.Payload[7] = 0x1; //SCM_PA_CL
+ Request.Payload[8] = connectionLabel / 256;
+ Request.Payload[9] = connectionLabel % 256;
+ }
+ else
+ {
+ Request.PayloadLen = 8;
+ Request.Payload[7] = 0x0; //SCM_NOT_PA
+ }
+ break;
+ case EP_Synchron:
+ if( SCM_IN == epDir )
+ {
+ Request.PayloadLen = 8;
+ Request.Payload[5] = 0x1; //SCM_PA_CL
+ Request.Payload[6] = connectionLabel / 256;
+ Request.Payload[7] = connectionLabel % 256;
+ }
+ else
+ {
+ Request.PayloadLen = 6;
+ Request.Payload[5] = 0x0; //SCM_NOT_PA
+ }
+ break;
+ default:
+ timeout = 1;
+ ConsolePrintf( PRIO_ERROR, RED"CreateMostSocket: Unsupported Data type"RESETCOLOR"\n" );
+ return;
+ }
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ uint8_t usbSocketHandle = 0xFF;
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 1;
+ if (success)
+ usbSocketHandle = Response.Payload[0];
+ 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 )->OnCreateMostSocketV1(device, success, Request.TargetAddress, epType,
+ epDir, blockWidthMost, connectionLabel, usbSocketHandle, tag);
+ }
+};
+
+class CV1_ConnectSockets : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ uint16_t nodeAddress;
+ EPDataType_t epType;
+ uint16_t inHandle;
+ uint16_t outHandle;
+ uint32_t tag;
+public:
+ CV1_ConnectSockets(CNetworkDevice *d, uint16_t nodeAddress, uint16_t iH,
+ uint16_t oH, uint32_t t) : device(d), inHandle(iH), outHandle(oH), tag(t)
+ {
+ ElementName = "CV1_ConnectSockets";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x405;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 2;
+ Request.Payload[0] = inHandle;
+ Request.Payload[1] = outHandle;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ uint8_t conHandle = 0xFF;
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 1;
+ if (success)
+ conHandle = Response.Payload[0];
+
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnConnectSocketsV1(device, success,
+ Request.TargetAddress, inHandle, outHandle, conHandle, tag);
+ }
+};
+
+class CV1_DestroySocket : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ uint8_t handle;
+ uint32_t tag;
+public:
+ CV1_DestroySocket(CNetworkDevice *d, int16_t nodeAddress, uint8_t h,
+ uint32_t t) : device(d), handle(h), tag(t)
+ {
+ ElementName = "CV1_DestroySocket";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x404;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 1;
+ Request.Payload[0] = handle;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnDestroySocketV1(device, (ISReturn_Success == result),
+ Request.TargetAddress, handle, tag);
+ }
+};
+
+class CV1_DisconnectSockets : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ uint8_t handle;
+ uint32_t tag;
+public:
+ CV1_DisconnectSockets(CNetworkDevice *d, int16_t nodeAddress, uint8_t h,
+ uint32_t t) : device(d), handle(h), tag(t)
+ {
+ ElementName = "CV1_DisconnectSockets";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x406;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 1;
+ Request.Payload[0] = handle;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnDisconnectSocketsV1(device, (ISReturn_Success == result),
+ Request.TargetAddress, handle, tag);
+ }
+};
+
+class CV1_StreamPortOpen : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ V1I2SPortClkDriveMode_t portMode;
+ V1I2SStreamingPortMode_t streamPortMode;
+ V1I2SStreamingDataFormat_t format;
+ uint32_t tag;
+public:
+ CV1_StreamPortOpen(CNetworkDevice *d, int16_t nodeAddress,
+ V1I2SPortClkDriveMode_t pm, V1I2SStreamingPortMode_t spm,
+ V1I2SStreamingDataFormat_t f, uint32_t t) : device(d), portMode(pm),
+ streamPortMode(spm), format(f), tag(t)
+ {
+ ElementName = "CV1_StreamPortOpen";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x400;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 4;
+ Request.Payload[0] = 0x03; //Streaming Port
+ Request.Payload[1] = portMode;
+ Request.Payload[2] = streamPortMode;
+ Request.Payload[3] = format;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnOpenI2SPortV1(device, (ISReturn_Success == result),
+ Request.TargetAddress, portMode, format, tag);
+ }
+};
+
+class CV1_StreamSocketCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ EPDirection_t epDir;
+ uint16_t blockWidthI2S;
+ V1I2SPin_t pin;
+ uint32_t tag;
+public:
+ CV1_StreamSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, EPDirection_t epd,
+ uint16_t bw, V1I2SPin_t p, uint32_t t) : device(d), epDir(epd),
+ blockWidthI2S(bw), pin(p), tag(t)
+ {
+ ElementName = "CV1_StreamSocketCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x403;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 6;
+ Request.Payload[0] = 0x03; //Streaming Port
+ Request.Payload[1] = epDir;
+ Request.Payload[2] = 0x0; //SyncData
+ Request.Payload[3] = blockWidthI2S / 256;
+ Request.Payload[4] = blockWidthI2S % 256;
+ Request.Payload[5] = (uint8_t)pin;
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ uint8_t i2sSocketHandle = 0xFF;
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 1;
+ if (success)
+ i2sSocketHandle = Response.Payload[0];
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnCreateI2SSocketV1(device, success,
+ Request.TargetAddress, epDir, blockWidthI2S, pin, i2sSocketHandle, tag);
+ }
+};
+
+class CV1_SplittedStreamSocketCreate : public CISSendMostMsgElement, public IISElementCallback
+{
+private:
+ CNetworkDevice *device;
+ EPDirection_t epDir;
+ uint16_t blockWidthI2S;
+ V1I2SPin_t pin;
+ uint32_t tag;
+public:
+ CV1_SplittedStreamSocketCreate(CNetworkDevice *d, uint16_t nodeAddress, EPDirection_t epd,
+ uint16_t bw, uint16_t splittedOffset, uint16_t blockWidthCombined, V1I2SPin_t p,
+ uint32_t t) : device(d), epDir(epd), blockWidthI2S(bw), pin(p), tag(t)
+ {
+ ElementName = "CV1_SplittedStreamSocketCreate";
+ WaitForResponse = true;
+ WaitForResponseOpType = CISOpType_RESULT;
+ Callback = this;
+
+ Request.IsValid = true;
+ Request.SourceAddress = 0x2;
+ Request.TargetAddress = nodeAddress;
+ Request.FBlock = 0x0;
+ Request.Func = 0x403;
+ Request.Inst = 0x00;
+ Request.OpType = CISOpType_STARTRESULT;
+ Request.PayloadLen = 7;
+ Request.Payload[0] = 0x03; //Streaming Port
+ Request.Payload[1] = epDir;
+ Request.Payload[2] = 0x0; //SyncData
+ Request.Payload[3] = blockWidthI2S / 256;
+ Request.Payload[4] = blockWidthI2S % 256;
+ Request.Payload[5] = (uint8_t)pin;
+ Request.Payload[6] = ( uint8_t )( splittedOffset & 0xFF );
+ }
+
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element)
+ {
+ uint8_t i2sSocketHandle = 0xFF;
+ bool success = (ISReturn_Success == result) && Response.PayloadLen >= 1;
+ if (success)
+ i2sSocketHandle = Response.Payload[0];
+ for( uint32_t i = 0; NULL != device && i < device->GetAmountOfListners(); i++ )
+ device->GetListener( i )->OnCreateI2SSocketV1(device, success,
+ Request.TargetAddress, epDir, blockWidthI2S, pin, i2sSocketHandle, tag);
+ }
+};
+
+#endif //INDUSTRIAL_STACK_API_V1_H \ No newline at end of file
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
diff --git a/Src/Network/IndustrialStack_LLD.cpp b/Src/Network/IndustrialStack_LLD.cpp
new file mode 100644
index 0000000..f025dec
--- /dev/null
+++ b/Src/Network/IndustrialStack_LLD.cpp
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ *
+ */
+
+//#define LLD_TRACE
+
+/*----------------------------------------------------------*/
+/*! \file */
+/*! \brief Base Board initialisation */
+/*----------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include "Console.h"
+#include "Board.h"
+#include "DriverConfiguration.h"
+#include "IndustrialStack_LLD.h"
+
+/*----------------------------------------------------------*/
+/* Static C helper functions */
+/*----------------------------------------------------------*/
+
+static void Queue_Init( Queue_t *queue )
+{
+ assert(NULL != queue);
+ queue->testPattern = QUEUE_TESTPATTERN;
+ queue->rxPos = 0;
+ queue->txPos = 0;
+ queue->pRx = queue->dataQueue;
+ queue->pTx = queue->dataQueue;
+}
+
+static QueueEntry_t *Queue_GetRxPtr( Queue_t *queue )
+{
+ assert(NULL != queue && QUEUE_TESTPATTERN == queue->testPattern);
+ QueueEntry_t *pEntry = NULL;
+ if( queue->txPos - queue->rxPos > 0 )
+ {
+ pEntry = queue->pRx;
+ }
+ return pEntry;
+}
+
+static void Queue_PopRx( Queue_t *queue )
+{
+ assert(NULL != queue && QUEUE_TESTPATTERN == queue->testPattern);
+ if( ++queue->pRx >= queue->dataQueue + BOARD_PMS_RX_QUEUE )
+ queue->pRx = queue->dataQueue;
+ ++queue->rxPos;
+}
+
+static QueueEntry_t *Queue_GetTxPtr( Queue_t *queue )
+{
+ assert(NULL != queue && QUEUE_TESTPATTERN == queue->testPattern);
+ QueueEntry_t *pEntry = NULL;
+ if( ( uint32_t )BOARD_PMS_RX_QUEUE + queue->rxPos - queue->txPos > 0 )
+ {
+ pEntry = queue->pTx;
+ }
+ return pEntry;
+}
+
+static void Queue_PopTx( Queue_t *queue )
+{
+ assert(NULL != queue && QUEUE_TESTPATTERN == queue->testPattern);
+ if( ++queue->pTx >= queue->dataQueue + BOARD_PMS_RX_QUEUE )
+ queue->pTx = queue->dataQueue;
+ ++queue->txPos;
+}
+
+static void *ReceiveThread( void *tag )
+{
+ assert(NULL != tag);
+ CIndustrialStackLld *var = ( CIndustrialStackLld * )tag;
+ while( var->allowThreadRun )
+ {
+ if( -1 == var->hControlRx )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"File handle for Control-RX is invalid, stopping reader thread."RESETCOLOR"\n" );
+ if (NULL != var->listener)
+ var->listener->OnReadThreadEnd(var);
+ pthread_exit( NULL );
+ }
+ QueueEntry_t *pEntry = Queue_GetTxPtr(&var->rxQueue);
+ if( NULL != pEntry )
+ {
+ int16_t payloadLen = 0;
+ payloadLen = read( var->hControlRx, pEntry->buffer, sizeof( pEntry->buffer ) );
+ if( payloadLen < 0 )
+ {
+ if( var->allowThreadRun )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Stopping reader thread, because of error: '%s'"RESETCOLOR"\n",
+ GetErrnoString() );
+ if (NULL != var->listener)
+ var->listener->OnReadThreadEnd(var);
+ }
+ pthread_exit( NULL );
+ }
+ else if( payloadLen != 0 )
+ {
+ pEntry->payloadLen = payloadLen;
+ Queue_PopTx(&var->rxQueue);
+#ifdef LLD_TRACE
+ {
+ ConsolePrintfStart( PRIO_HIGH, BLUE"%04d: MSG_RX: ", GetTickCountWord());
+ for ( int16_t i = 0; i < pEntry->payloadLen; i++ )
+ {
+ ConsolePrintfContinue( "%02X ", pEntry->buffer[i] );
+ }
+ ConsolePrintfExit(RESETCOLOR"\n");
+ }
+#endif
+ }
+ }
+ else
+ {
+ ConsolePrintf( PRIO_ERROR, RED"WARNING, RX QUEUE FULL !!\nPlease increase BOARD_PMS_RX_QUEUE value, or increase polling speed\n"RESETCOLOR"\n" );
+ usleep( 10000 );
+ }
+ }
+ ConsolePrintf( PRIO_LOW, "Control Receive Thread ends\n" );
+ if( var->allowThreadRun && NULL != var->listener)
+ var->listener->OnReadThreadEnd(var);
+ pthread_exit( NULL );
+}
+
+static void *SendThread( void *tag )
+{
+ assert(NULL != tag);
+ CIndustrialStackLld *var = ( CIndustrialStackLld * )tag;
+ while( var->allowThreadRun )
+ {
+ sem_wait( &var->txSem );
+ if (!var->allowThreadRun)
+ pthread_exit( NULL );
+ QueueEntry_t *pEntry = Queue_GetRxPtr( &var->txQueue );
+ assert(NULL != pEntry);
+ if( -1 == var->hControlTx )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"File handle for Control-TX is invalid, stopping send thread."RESETCOLOR"\n" );
+ pthread_exit( NULL );
+ }
+#ifdef LLD_TRACE
+ {
+ uint32_t i;
+ ConsolePrintfStart( PRIO_MEDIUM, YELLOW"%04d: MSG_TX: ", GetTickCountWord());
+ for ( i = 0; i < pEntry->payloadLen; i++ )
+ {
+ ConsolePrintfContinue( "%02X ", pEntry->buffer[i] );
+ }
+ ConsolePrintfExit(RESETCOLOR"\n");
+ }
+#endif
+ if( write( var->hControlTx, pEntry->buffer, pEntry->payloadLen ) != pEntry->payloadLen )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Failed to send %d bytes to the MOST control channel"RESETCOLOR"\n", pEntry->payloadLen );
+ usleep(1000);
+ }
+ else
+ {
+ Queue_PopRx(&var->txQueue);
+ }
+
+ }
+ pthread_exit( NULL );
+}
+
+/*----------------------------------------------------------*/
+/* Public method implementations */
+/*----------------------------------------------------------*/
+
+CIndustrialStackLld::CIndustrialStackLld( int controlRxHandle, int controlTxHandle )
+ : hControlRx(controlRxHandle), hControlTx(controlTxHandle), allowThreadRun(true), listener(NULL)
+{
+ Queue_Init(&rxQueue);
+ Queue_Init(&txQueue);
+
+ if (sem_init(&txSem, 0, 0) == -1)
+ {
+ ConsolePrintf(PRIO_ERROR, RED"CIndustrialStackLld constructor: sem_init failed"RESETCOLOR"\n");
+ return;
+ }
+
+ pthread_create( &rxThread, NULL, ReceiveThread, this );
+ pthread_create( &txThread, NULL, SendThread, this );
+}
+
+CIndustrialStackLld::~CIndustrialStackLld()
+{
+ void *dummy;
+ allowThreadRun = false;
+ sem_post( &txSem );
+
+ pthread_join( txThread, &dummy );
+ pthread_join( rxThread, &dummy );
+
+ sem_destroy( &txSem );
+}
+
+void CIndustrialStackLld::ClearQueues()
+{
+ ConsolePrintf( PRIO_LOW, "Clearing INIC queues\n" );
+ QueueEntry_t *pEntry;
+ while( NULL != ( pEntry = Queue_GetRxPtr(&rxQueue) ) )
+ Queue_PopRx(&rxQueue);
+ while( NULL != ( pEntry = Queue_GetRxPtr(&txQueue) ) )
+ Queue_PopRx(&txQueue);
+}
+
+uint16_t CIndustrialStackLld::DataAvailable()
+{
+ uint16_t readLen = 0;
+ QueueEntry_t *pEntry = Queue_GetRxPtr(&rxQueue);
+ if( NULL != pEntry )
+ readLen = pEntry->payloadLen;
+ return readLen;
+}
+
+uint16_t CIndustrialStackLld::Read( uint8_t *pData, uint32_t bufferLen )
+{
+ uint16_t readLen = 0;
+ QueueEntry_t *pEntry = Queue_GetRxPtr(&rxQueue);
+ if( NULL != pData && NULL != pEntry )
+ {
+ readLen = pEntry->payloadLen;
+ if (readLen > bufferLen)
+ {
+ ConsolePrintf(PRIO_ERROR, RED"CIndustrialStackLld::Read buffer"\
+ " length is too small"RESETCOLOR"\n");
+ readLen = bufferLen;
+ }
+ memcpy( pData, pEntry->buffer, readLen );
+ Queue_PopRx(&rxQueue);
+ }
+ return readLen;
+}
+
+bool CIndustrialStackLld::Write( uint16_t wLen, uint8_t *pData )
+{
+ if( -1 == hControlTx )
+ return false;
+ QueueEntry_t *pEntry = Queue_GetTxPtr( &txQueue );
+ if( NULL != pData && NULL != pEntry )
+ {
+ memcpy( pEntry->buffer, pData, wLen );
+ pEntry->payloadLen = wLen;
+ Queue_PopTx( &txQueue );
+ sem_post( &txSem );
+ return true;
+ }
+ return false;
+}
diff --git a/Src/Network/IndustrialStack_LLD.h b/Src/Network/IndustrialStack_LLD.h
new file mode 100644
index 0000000..8ae9738
--- /dev/null
+++ b/Src/Network/IndustrialStack_LLD.h
@@ -0,0 +1,148 @@
+/*
+ * 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 component implements the MOST low level driver.
+ */
+/*----------------------------------------------------------*/
+#ifndef INDUSTRIAL_STACK_LLD_H
+#define INDUSTRIAL_STACK_LLD_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include "IndustrialStack_Types.h"
+
+#define BOARD_PMS_RX_QUEUE 256
+#define BOARD_PMS_RX_SIZE 64
+#define BOARD_PMS_TX_SIZE 64
+
+typedef struct
+{
+ int16_t payloadLen;
+ uint8_t buffer[BOARD_PMS_RX_SIZE];
+} QueueEntry_t;
+
+#define QUEUE_TESTPATTERN (0x34547382)
+typedef struct
+{
+ uint32_t testPattern;
+ QueueEntry_t dataQueue[BOARD_PMS_RX_QUEUE];
+ QueueEntry_t *pRx;
+ QueueEntry_t *pTx;
+ volatile uint32_t rxPos;
+ volatile uint32_t txPos;
+} Queue_t;
+
+class CIndustrialStackLld
+{
+private:
+ pthread_t txThread;
+ pthread_t rxThread;
+public:
+ ///Do not use directly! (Called internally from thread context)
+ Queue_t txQueue;
+ ///Do not use directly! (Called internally from thread context)
+ Queue_t rxQueue;
+ ///Do not use directly! (Called internally from thread context)
+ int hControlRx;
+ ///Do not use directly! (Called internally from thread context)
+ int hControlTx;
+ ///Do not use directly! (Called internally from thread context)
+ bool allowThreadRun;
+ ///Do not use directly! (Called internally from thread context)
+ sem_t txSem;
+
+ CIndustrialStackLldCB *listener;
+
+ /*----------------------------------------------------------*/
+ /*! \brief initializes LLD
+ *
+ * \param controlRxHandle File handle for the RX character device
+ * \param controlRxHandle File handle for the TX character device
+ * \return nothing.
+ */
+ /*----------------------------------------------------------*/
+ CIndustrialStackLld( int controlRxHandle, int controlTxHandle );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief deinitializes LLD
+ */
+ /*----------------------------------------------------------*/
+ ~CIndustrialStackLld();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief determins if INIC has something to read
+ *
+ * \return The amount of data, which will be delivered by the next call of Read
+ */
+ /*----------------------------------------------------------*/
+ uint16_t DataAvailable();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief receive a control message via USB.
+ *
+ * \param pData - message data
+ *
+ * \return The amount of bytes read.
+ */
+ /*----------------------------------------------------------*/
+ uint16_t Read( uint8_t *pData, uint32_t bufferLen );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Clearing RX and TX queues.
+ *
+ * \return nothing
+ */
+ /*----------------------------------------------------------*/
+ void ClearQueues();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief send a control message via USB.
+ *
+ * \param wLen - length of message in bytes
+ * \param pData - message data
+ *
+ * \return True if no error.
+ */
+ /*----------------------------------------------------------*/
+ bool Write( uint16_t wLen, uint8_t *pData );
+
+};
+
+class CIndustrialStackLldCB
+{
+public:
+ virtual void OnReadThreadEnd(CIndustrialStackLld *lld) = 0;
+};
+
+#endif // INDUSTRIAL_STACK_LLD_H
diff --git a/Src/Network/IndustrialStack_MNS.cpp b/Src/Network/IndustrialStack_MNS.cpp
new file mode 100644
index 0000000..257db40
--- /dev/null
+++ b/Src/Network/IndustrialStack_MNS.cpp
@@ -0,0 +1,414 @@
+/*
+ * 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 (NetService part).
+ */
+/*----------------------------------------------------------*/
+
+#define ENABLE_INIC_WATCHDOG true
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "IndustrialStack_MNS.h"
+#include "IndustrialStack_Types.h"
+#include "Board.h"
+#include "Console.h"
+
+static bool CheckMnswPointer(void *inst_ptr, const char *functionName);
+static void Lld_CtrlStartC( Mns_Lld_Api_t *callbacks_ptr, void *ns_ptr, void *inst_ptr );
+static void Lld_CtrlStopC( void *inst_ptr );
+static void Lld_CtrlTxTransmitC( Mns_Lld_TxMsg_t *msg_ptr, void *inst_ptr );
+static void Lld_CtrlRxMsgAvailableC( void *inst_ptr );
+static uint16_t GetTickCountWordC();
+static void OnMnslEventC( Mnsl_Event_t event_code, void *inst_ptr );
+static void OnMnslServiceC( void *inst_ptr );
+static void *OnMnslAmsAllocMemC( void *inst_ptr, uint16_t mem_size, Mns_Ams_MemUsage_t type, void** custom_info_pptr );
+static void OnMnslAmsFreeMemC( void *inst_ptr, void *mem_ptr, Mns_Ams_MemUsage_t type, void* custom_info_ptr );
+static void OnIcmRx( void *inst_ptr, Msg_MostTel_t *pRx );
+static void OnRcmRx( void *inst_ptr, Msg_MostTel_t *pRx );
+static void OnMcmRx( void *inst_ptr, Msg_MostTel_t *pRx );
+static void OnTransmissionStatus(void *self, Msg_MostTel_t *tel_ptr, Mns_MsgTxStatus_t status);
+
+CISNetServiceWrapper::CISNetServiceWrapper(uint8_t deviceApi, int controlRxHandle, int controlTxHandle)
+ : testPattern(MNSW_TESTPATTERN), inicWriteError( false ), pMnsInterface(NULL), pMnsInst(NULL)
+ , isSynced(false), wrapperCB(NULL)
+{
+ if( 2 != deviceApi && 3 != deviceApi )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"CISNetServiceWrapper was called with deviceApi set"\
+ " to %d. This is not supported by this branch of NetworkManager"\
+ RESETCOLOR"\n", deviceApi );
+ }
+
+ lld = new CIndustrialStackLld(controlRxHandle, controlTxHandle);
+ lld->listener = this;
+
+ memset(&pLldCb, 0, sizeof(pLldCb));
+ pLldCb.start_fptr = &Lld_CtrlStartC;
+ pLldCb.stop_fptr = &Lld_CtrlStopC;
+ pLldCb.rx_available_fptr = &Lld_CtrlRxMsgAvailableC;
+ pLldCb.tx_transmit_fptr = &Lld_CtrlTxTransmitC;
+
+ Mnsl_InitData_t initData;
+ Mnsl_SetDefaultConfig(&initData, ENABLE_INIC_WATCHDOG);
+ initData.lld.start_fptr = &Lld_CtrlStartC;
+ initData.lld.stop_fptr = &Lld_CtrlStopC;
+ initData.lld.rx_available_fptr = &Lld_CtrlRxMsgAvailableC;
+ initData.lld.tx_transmit_fptr = &Lld_CtrlTxTransmitC;
+
+ initData.general.get_tickcount_fptr = &GetTickCountWordC;
+ initData.general.event_fptr = &OnMnslEventC;
+ initData.general.request_service_fptr = &OnMnslServiceC;
+
+ initData.pms.active_fifos = MNSL_FIFOS_MCM_ICM_RCM;
+ initData.pms.compressed = (2 == deviceApi);
+
+ initData.ams.rx_alloc_mem_fptr = &OnMnslAmsAllocMemC;
+ initData.ams.rx_free_mem_fptr = &OnMnslAmsFreeMemC;
+
+ Mnsl_Init( &mnsl, &initData, this );
+
+ icm_inst_ptr = Mnsl_GetIcmTransceiver( &mnsl ); // Retrieve ICM instance
+ rcm_inst_ptr = Mnsl_GetRcmTransceiver( &mnsl ); // Retrieve RCM instance
+ mcm_inst_ptr = Mnsl_GetMcmTransceiver( &mnsl ); // Retrieve MCM instance
+
+ Trcv_RxAssignReceiver( icm_inst_ptr, &OnIcmRx, this ); // Assign ICM Receiver Callback
+ Trcv_RxAssignReceiver( rcm_inst_ptr, &OnRcmRx, this ); // Assign ICM Receiver Callback
+ Trcv_RxAssignReceiver( mcm_inst_ptr, &OnMcmRx, this ); // Assign ICM Receiver Callback
+
+ Mnsl_Synchronize( &mnsl );
+}
+
+CISNetServiceWrapper::~CISNetServiceWrapper()
+{
+ if (NULL != lld)
+ {
+ delete lld;
+ lld = NULL;
+ }
+}
+
+void CISNetServiceWrapper::ServiceMns()
+{
+ assert(NULL != lld);
+ uint16_t wLen;
+ while( 0 != ( wLen = lld->DataAvailable() ) )
+ {
+ if (NULL != pMnsInterface)
+ {
+ Mns_Lld_RxMsg_t *pRxMsg = pMnsInterface->rx_allocate_fptr( pMnsInst, wLen );
+ if( pRxMsg )
+ {
+ if (wLen != lld->Read( pRxMsg->data_ptr, wLen ))
+ ConsolePrintf( PRIO_ERROR, RED"! LLD read error"RESETCOLOR"\n" ); //Must not happen
+ pRxMsg->data_size = wLen;
+ pMnsInterface->rx_receive_fptr( pMnsInst, pRxMsg );
+ Mnsl_Service( &mnsl );
+ }
+ else
+ ConsolePrintf( PRIO_ERROR, RED"! out of message memory"RESETCOLOR"\n" );
+ }
+ }
+ Mnsl_Service( &mnsl );
+}
+
+void CISNetServiceWrapper::AddListener(IISNetServiceWrapperCB *rcvListener)
+{
+ wrapperCB = rcvListener;
+}
+
+bool CISNetServiceWrapper::SendMostMessage(CISMostMsg *msg)
+{
+ assert(NULL != msg);
+ assert(msg->IsValid);
+
+ CTransceiver *tr = NULL;
+
+ if (0x1 == msg->TargetAddress || 0x100 == msg->TargetAddress)
+ tr = icm_inst_ptr;
+ else if (0x0 == msg->FBlock || 0x1 == msg->FBlock)
+ tr = rcm_inst_ptr;
+ else
+ tr = mcm_inst_ptr;
+
+ Msg_MostTel_t *tel = Trcv_TxAllocateMsg( tr, msg->PayloadLen );
+ if( NULL == tel )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Trcv_TxAllocateMsg failed. Len:"\
+ " %u, Message-Type=%s"RESETCOLOR"\n", msg->PayloadLen,
+ (tr == icm_inst_ptr ? "ICM" : tr == rcm_inst_ptr ? "RCM" : "MCM"));
+ return false;
+ }
+ tel->source_addr = msg->SourceAddress;
+ tel->destination_addr = msg->TargetAddress;
+ tel->id.fblock_id = msg->FBlock;
+ tel->id.function_id = msg->Func;
+ tel->id.instance_id = msg->Inst;
+ tel->id.op_type = (Mns_OpType_t)msg->OpType;
+ tel->tel.tel_len = msg->PayloadLen;
+ tel->tel.tel_id = 0;
+ if (0 != msg->PayloadLen)
+ {
+ if (NULL != tel->tel.tel_data_ptr)
+ {
+ memcpy(tel->tel.tel_data_ptr, msg->Payload, msg->PayloadLen);
+ } else {
+ ConsolePrintf(PRIO_ERROR, RED"CISNetServiceWrapper::SendMostMessage,"\
+ " packet has NULL pointer payload"RESETCOLOR"\n");
+ Trcv_TxReleaseMsg(tel);
+ return false;
+ }
+ }
+ Trcv_TxSendMsgExt( tr, tel, OnTransmissionStatus, NULL );
+ return true;
+}
+
+void CISNetServiceWrapper::Unsynchronize()
+{
+ Mnsl_Unsynchronize( &mnsl, true );
+}
+
+void CISNetServiceWrapper::OnReadThreadEnd(CIndustrialStackLld *lld)
+{
+ if (NULL != wrapperCB)
+ wrapperCB->OnControlReadEnd();
+}
+
+void CISNetServiceWrapper::OnCtrlTxTransmit( Mns_Lld_TxMsg_t *msg_ptr)
+{
+ assert(NULL != msg_ptr);
+ assert(NULL != pMnsInterface);
+ if( msg_ptr && pMnsInterface )
+ {
+ assert(NULL != lld);
+ Mns_Mem_Buffer_t *pMemBuf;
+#define MAX_DATA_LEN 72
+ uint8_t data[MAX_DATA_LEN];
+ uint8_t *pW = data;
+ for( pMemBuf = msg_ptr->memory_ptr; pMemBuf != NULL;
+ pMemBuf = pMemBuf->next_buffer_ptr )
+ {
+ if( pW + pMemBuf->data_size >= data + MAX_DATA_LEN )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"invalid size"RESETCOLOR"\n" );
+ return;
+ }
+ memcpy( pW, pMemBuf->data_ptr, pMemBuf->data_size );
+ pW += pMemBuf->data_size;
+ }
+
+ if( !lld->Write( pW - data, data ) )
+ {
+ if (!inicWriteError)
+ {
+ inicWriteError = true;
+ ConsolePrintf( PRIO_ERROR, RED"! Unable to write to INIC!"RESETCOLOR"\n" );
+ }
+ }
+ else inicWriteError = false;
+
+ pMnsInterface->tx_release_fptr( pMnsInst, msg_ptr );
+ }
+}
+
+void CISNetServiceWrapper::OnMnslEvent( Mnsl_Event_t event_code )
+{
+ bool oldSyncState = isSynced;
+ switch( event_code )
+ {
+ case MNSL_EVENT_SYNC_COMPLETE:
+ isSynced = true;
+ ConsolePrintf( PRIO_MEDIUM, "MNSL Event Callback notifies: MNSL_EVENT_SYNC_COMPLETE\n" );
+ break;
+ case MNSL_EVENT_SYNC_FAILED:
+ isSynced = false;
+ ConsolePrintf( PRIO_ERROR, YELLOW"MNSL Event Callback notifies: MNSL_EVENT_SYNC_FAILED" \
+ ", retrying..\nMake sure that local INIC runs Firmware V2.3.0 or later!"RESETCOLOR"\n" );
+ Mnsl_Synchronize( &mnsl );
+ return; /* Do not report the event */
+ case MNSL_EVENT_SYNC_LOST:
+ isSynced = false;
+ ConsolePrintf( PRIO_ERROR, "MNSL Event Callback notifies: MNSL_EVENT_SYNC_LOST\n" );
+ break;
+ case MNSL_EVENT_UNSYNC_COMPLETE:
+ isSynced = false;
+ ConsolePrintf( PRIO_MEDIUM, YELLOW"MNSL Event Callback notifies: MNSL_EVENT_UNSYNC_COMPLETE, syncing again.."RESETCOLOR"\n" );
+ Mnsl_Synchronize( &mnsl );
+ return; /* Do not report the event */
+ case MNSL_EVENT_UNSYNC_FAILED:
+ isSynced = false;
+ ConsolePrintf( PRIO_ERROR, RED"MNSL Event Callback notifies: MNSL_EVENT_UNSYNC_FAILED"RESETCOLOR"\n" );
+ Mnsl_Synchronize( &mnsl );
+ break;
+ default:
+ ConsolePrintf( PRIO_ERROR, "MNSL Event Callback notifies: UNKNOWN CODE\n" );
+ break;
+ }
+ if (NULL != wrapperCB && oldSyncState != isSynced)
+ {
+ wrapperCB->OnSyncStateChanged(isSynced);
+ }
+}
+
+void CISNetServiceWrapper::OnMessage( Msg_MostTel_t *pRx, CTransceiver *pTr )
+{
+ assert(NULL != pRx);
+ assert(pRx->tel.tel_len <= MAX_PAYLOAD_SIZE);
+ if (NULL == wrapperCB)
+ return;
+ CISMostMsg msg;
+ msg.IsValid = true;
+ msg.SourceAddress = pRx->source_addr;
+ msg.TargetAddress = pRx->destination_addr;
+ msg.FBlock = pRx->id.fblock_id;
+ msg.Func = pRx->id.function_id;
+ msg.Inst = pRx->id.instance_id;
+ msg.OpType = (CISOpType_t) pRx->id.op_type;
+ msg.PayloadLen = pRx->tel.tel_len;
+ memcpy(msg.Payload, pRx->tel.tel_data_ptr, msg.PayloadLen);
+ Trcv_RxReleaseMsg(pTr, pRx);
+ wrapperCB->OnReceivedMostMessage(&msg);
+}
+
+/*----------------------------------------
+ * Private helper functions and C wrapper:
+ *----------------------------------------
+ */
+static bool CheckMnswPointer(void *inst_ptr, const char *functionName)
+{
+ if( NULL == inst_ptr || MNSW_TESTPATTERN != ( ( CISNetServiceWrapper * )inst_ptr )->testPattern )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Parameter bug in %s"RESETCOLOR"\n", functionName );
+ assert(false);
+ return true;
+ }
+ return false;
+}
+static void Lld_CtrlStartC( Mns_Lld_Api_t *callbacks_ptr, void *ns_ptr, void *inst_ptr )
+{
+ if (CheckMnswPointer(inst_ptr, "Lld_CtrlStart")) return;
+ CISNetServiceWrapper *mnsw = ( CISNetServiceWrapper * )inst_ptr;
+ mnsw->pMnsInterface = callbacks_ptr;
+ mnsw->pMnsInst = ns_ptr;
+}
+static void Lld_CtrlStopC( void *inst_ptr )
+{
+ if (CheckMnswPointer(inst_ptr, "Lld_CtrlStop")) return;
+ CISNetServiceWrapper *mnsw = ( CISNetServiceWrapper * )inst_ptr;
+ mnsw->pMnsInterface = 0;
+ mnsw->pMnsInst = 0;
+}
+static void Lld_CtrlTxTransmitC( Mns_Lld_TxMsg_t *msg_ptr, void *inst_ptr )
+{
+ if (CheckMnswPointer(inst_ptr, "Lld_CtrlTxTransmit")) return;
+ CISNetServiceWrapper *mnsw = ( CISNetServiceWrapper * )inst_ptr;
+ mnsw->OnCtrlTxTransmit(msg_ptr);
+}
+static void Lld_CtrlRxMsgAvailableC( void *inst_ptr )
+{
+ //Unused
+}
+static uint16_t GetTickCountWordC()
+{
+ return GetTickCountWord();
+}
+static void OnMnslEventC( Mnsl_Event_t event_code, void *inst_ptr )
+{
+ if (CheckMnswPointer(inst_ptr, "OnMnslEvent")) return;
+ CISNetServiceWrapper *mnsw = ( CISNetServiceWrapper * )inst_ptr;
+ mnsw->OnMnslEvent(event_code);
+}
+static void OnMnslServiceC( void *inst_ptr )
+{
+ //Unused
+}
+static void *OnMnslAmsAllocMemC( void *inst_ptr, uint16_t mem_size, Mns_Ams_MemUsage_t type, void** custom_info_pptr )
+{
+ if( 0 == mem_size )
+ return NULL;
+ return calloc( mem_size, 1 );
+}
+static void OnMnslAmsFreeMemC( void *inst_ptr, void *mem_ptr, Mns_Ams_MemUsage_t type, void* custom_info_ptr )
+{
+ if( NULL != mem_ptr )
+ free( mem_ptr );
+}
+static void OnIcmRx( void *inst_ptr, Msg_MostTel_t *pRx )
+{
+ if (CheckMnswPointer(inst_ptr, "OnIcmRx")) return;
+ CISNetServiceWrapper *mnsw = ( CISNetServiceWrapper * )inst_ptr;
+ mnsw->OnMessage(pRx, mnsw->icm_inst_ptr);
+}
+static void OnRcmRx( void *inst_ptr, Msg_MostTel_t *pRx )
+{
+ if (CheckMnswPointer(inst_ptr, "OnRcmRx")) return;
+ CISNetServiceWrapper *mnsw = ( CISNetServiceWrapper * )inst_ptr;
+ mnsw->OnMessage(pRx, mnsw->rcm_inst_ptr);
+}
+static void OnMcmRx( void *inst_ptr, Msg_MostTel_t *pRx )
+{
+ if (CheckMnswPointer(inst_ptr, "OnMcmRx")) return;
+ CISNetServiceWrapper *mnsw = ( CISNetServiceWrapper * )inst_ptr;
+ mnsw->OnMessage(pRx, mnsw->mcm_inst_ptr);
+}
+
+static void OnTransmissionStatus(void *self, Msg_MostTel_t *tel_ptr, Mns_MsgTxStatus_t status)
+{
+ if (MNS_MSG_STAT_OK != status)
+ {
+ ConsolePrintf(PRIO_ERROR, RED"Transmission failed for addr=0x%X FBlock=0x%X " \
+ "Function=0x%X, error-code=0x%X"RESETCOLOR"\n", tel_ptr->destination_addr,
+ tel_ptr->id.fblock_id, tel_ptr->id.function_id, status);
+ }
+ Trcv_TxReleaseMsg(tel_ptr);
+}
+
+#define TRACE_BUFFER_SZ 200
+#include <stdarg.h>
+#include <stdio.h>
+void My_TraceInfo(uint8_t mns_inst_id, const char module_str[], const char entry_str[], uint16_t vargs_cnt, ...)
+{
+ char_t outbuf[TRACE_BUFFER_SZ];
+ va_list argptr;
+ uint16_t timestamp = GetTickCountWord();
+ va_start(argptr, vargs_cnt);
+ vsprintf(outbuf, entry_str, argptr);
+ va_end(argptr);
+ ConsolePrintf(PRIO_HIGH, YELLOW"[%u] | %u | Info | %s | %s"RESETCOLOR"\n", mns_inst_id, timestamp, module_str, outbuf);
+}
+
+void My_TraceError(uint8_t mns_inst_id, const char module_str[], const char entry_str[], uint16_t vargs_cnt, ...)
+{
+ char_t outbuf[TRACE_BUFFER_SZ];
+ va_list argptr;
+ uint16_t timestamp = GetTickCountWord();
+ va_start(argptr, vargs_cnt);
+ vsprintf(outbuf, entry_str, argptr);
+ va_end(argptr);
+ ConsolePrintf(PRIO_ERROR, RED"[%u] | %u | Error | %s | %s"RESETCOLOR"\n", mns_inst_id, timestamp, module_str, outbuf);
+}
diff --git a/Src/Network/IndustrialStack_MNS.h b/Src/Network/IndustrialStack_MNS.h
new file mode 100644
index 0000000..7cb28ee
--- /dev/null
+++ b/Src/Network/IndustrialStack_MNS.h
@@ -0,0 +1,84 @@
+/*
+ * 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 (NetService part).
+ */
+/*----------------------------------------------------------*/
+
+#ifndef INDUSTRIAL_STACK_MNS_H
+#define INDUSTRIAL_STACK_MNS_H
+
+#include <assert.h>
+#include "IndustrialStack_Types.h"
+#include "IndustrialStack_LLD.h"
+#include "mns_types_cfg.h"
+#include "mnsl.h"
+
+#define MNSW_TESTPATTERN ((uint32_t)0xA1B2C3D4)
+
+class IISNetServiceWrapperCB
+{
+public:
+ virtual void OnReceivedMostMessage(CISMostMsg *rcvMessage) = 0;
+ virtual void OnSyncStateChanged(bool isSynced) = 0;
+ virtual void OnControlReadEnd() = 0;
+};
+
+class CISNetServiceWrapper : public CIndustrialStackLldCB
+{
+public:
+ const uint32_t testPattern;
+ bool inicWriteError;
+ Mns_Lld_Api_t *pMnsInterface;
+ void *pMnsInst;
+ CTransceiver *icm_inst_ptr;
+ CTransceiver *rcm_inst_ptr;
+ CTransceiver *mcm_inst_ptr;
+private:
+ CMnsl mnsl;
+ Mns_Lld_Callbacks_t pLldCb;
+ bool isSynced;
+ IISNetServiceWrapperCB *wrapperCB;
+ CIndustrialStackLld *lld;
+
+public:
+ CISNetServiceWrapper(uint8_t deviceApi, int controlRxHandle, int controlTxHandle);
+ virtual ~CISNetServiceWrapper();
+ void ServiceMns();
+ void AddListener(IISNetServiceWrapperCB *rcvListener);
+
+ bool SendMostMessage(CISMostMsg *sndMessage);
+ void Unsynchronize();
+
+public:
+ //Will be called from LLD, do not call directly
+ virtual void OnReadThreadEnd(CIndustrialStackLld *lld);
+ //All this functions will be called by the C wrappers, do not call them directly
+ void OnCtrlTxTransmit( Mns_Lld_TxMsg_t *msg_ptr);
+ void OnMnslEvent( Mnsl_Event_t event_code );
+ void OnMessage( Msg_MostTel_t *pRx, CTransceiver *pTr );
+};
+
+#endif //INDUSTRIAL_STACK_MNS_H
diff --git a/Src/Network/IndustrialStack_Types.h b/Src/Network/IndustrialStack_Types.h
new file mode 100644
index 0000000..21bba51
--- /dev/null
+++ b/Src/Network/IndustrialStack_Types.h
@@ -0,0 +1,159 @@
+/*
+ * 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 (type defnitions and common classes).
+ */
+/*----------------------------------------------------------*/
+
+#ifndef INDUSTRIAL_STACK_TYPES_H
+#define INDUSTRIAL_STACK_TYPES_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "SafeVector.h"
+typedef enum
+{
+ ISReturn_NoChange,
+ ISReturn_Success,
+ ISReturn_Failure,
+ ISReturn_Timeout
+} ISReturn_t;
+
+typedef enum
+{
+ CISOpType_INVALID = 0xFF,
+ CISOpType_SET = 0x0,
+ CISOpType_GET = 0x1,
+ CISOpType_SETGET = 0x2,
+ CISOpType_INC = 0x3,
+ CISOpType_DEC = 0x4,
+ CISOpType_GETINTERFACE = 0x5,
+ CISOpType_STATUS = 0xC,
+ CISOpType_INTERFACE = 0xE,
+ CISOpType_ERROR = 0xF,
+ CISOpType_START = 0x0,
+ CISOpType_ABORT = 0x1,
+ CISOpType_STARTRESULT = 0x2,
+ CISOpType_STARTRESULTACK = 0x6,
+ CISOpType_ABORTACK = 0x7,
+ CISOpType_STARTACK = 0x8,
+ CISOpType_ERRORACK = 0x9,
+ CISOpType_PROCESSINGACK = 0xA,
+ CISOpType_PROCESSING = 0xB,
+ CISOpType_RESULT = 0xC,
+ CISOpType_RESULTACK = 0xD,
+ CISOpType_REPORTS = 0x9
+} CISOpType_t;
+
+class CIndustrialStack;
+class IISElement;
+class IISElementCallback;
+class CISWaitElement;
+class CISMostMsg;
+class CSInternalEvent;
+class CISSendMostMsgElement;
+class CISDeviceQueue;
+class CIndustrialStackLldCB;
+class CV1_OnMostRx;
+class CV2_OnMostRx;
+class CV3_OnMostRx;
+
+class IISElement
+{
+private:
+ int32_t refCount;
+public:
+ const char *ElementName;
+ IISElementCallback *Callback;
+ IISElement() : refCount(1), ElementName("Not set"), Callback(NULL) { }
+ virtual ~IISElement() {}
+
+ virtual ISReturn_t Service(CIndustrialStack *iStack, uint32_t time) = 0;
+ virtual ISReturn_t OnMostMessage(CIndustrialStack *iStack, CISMostMsg *rcvMessage) = 0;
+
+ void AddReference()
+ {
+ ++refCount;
+ }
+
+ void RemoveReference()
+ {
+ if( 0 == --refCount )
+ delete this;
+ }
+};
+
+class CISMostMsg
+{
+#define MAX_PAYLOAD_SIZE 45
+public:
+ bool IsValid;
+ uint32_t SourceAddress;
+ uint32_t TargetAddress;
+ uint32_t FBlock;
+ uint32_t Func;
+ uint32_t Inst;
+ CISOpType_t OpType;
+ uint32_t PayloadLen;
+ uint8_t Payload[MAX_PAYLOAD_SIZE];
+
+ CISMostMsg() : IsValid(false), SourceAddress(0xFFFFFFFF), TargetAddress(0xFFFFFFFF),
+ FBlock(0xFFFFFFFF), Func(0xFFFFFFFF), Inst(0xFFFFFFFF),
+ OpType(CISOpType_INVALID), PayloadLen(0)
+ { }
+
+ void DeepCopy(CISMostMsg *msg)
+ {
+ IsValid = msg->IsValid;
+ SourceAddress = msg->SourceAddress;
+ TargetAddress = msg->TargetAddress;
+ FBlock = msg->FBlock;
+ Func = msg->Func;
+ Inst = msg->Inst;
+ OpType = msg->OpType;
+ PayloadLen = msg->PayloadLen;
+ memcpy(Payload, msg->Payload, PayloadLen);
+ }
+};
+
+class IISElementCallback
+{
+public:
+ virtual void ElementProcessed(CIndustrialStack *iStack, ISReturn_t result, IISElement *element) = 0;
+};
+
+class CISDeviceQueue
+{
+private:
+ uint16_t nodeAddress;
+public:
+ CSafeVector<IISElement *> elements;
+
+ CISDeviceQueue(uint16_t address) : nodeAddress(address) { }
+ uint16_t GetNodeAddress() { return nodeAddress; }
+};
+
+#endif //INDUSTRIAL_STACK_TYPES_H \ No newline at end of file
diff --git a/Src/Network/Network.cpp b/Src/Network/Network.cpp
new file mode 100644
index 0000000..0c4b10d
--- /dev/null
+++ b/Src/Network/Network.cpp
@@ -0,0 +1,433 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include "SafeVector.h"
+#include "Network.h"
+#include "NetworkDevice.h"
+#include "DriverConfiguration.h"
+#include "MacAddr.h"
+#include "Board.h"
+#include "Console.h"
+#include "NodeDatabase.h"
+
+using namespace std;
+
+static CNetwork *staticInstance = NULL;
+CSafeVector<CNetworkDevice *> CNetwork::allNetworkDevices;
+
+CNetwork::CNetwork() : CThread( "CNetwork", false ), allowNetworkRun( false ),
+ vodXml( NULL ), connectionBitMask( 0 ), promiscuous( false ), retryCounter( 0 ),
+ retryExecTime( 0 )
+{
+ searchPath[0] = 0;
+ sem_init( &vodXmlMutex, 0, 1 ); //Mutex, initialized to 1 => sem_wait will block at 2nd call
+ Start();
+}
+
+CNetwork::~CNetwork()
+{
+ ConsolePrintf( PRIO_LOW, "Destructor of network called\r\n" );
+ Stop();
+ allowNetworkRun = false;
+ CloseAllNetworkDevices();
+ sem_wait( &vodXmlMutex );
+ if( NULL != vodXml )
+ {
+ delete vodXml;
+ vodXml = NULL;
+ }
+ sem_post( &vodXmlMutex );
+ staticInstance = NULL;
+ ConsolePrintf( PRIO_LOW, "end network\r\n" );
+}
+
+CNetwork *CNetwork::GetInstance( void )
+{
+ if( NULL == staticInstance )
+ {
+ staticInstance = new CNetwork();
+ }
+ return staticInstance;
+}
+
+void CNetwork::AddListener( CNetworkListner *listener )
+{
+ allListeners.PushBack( listener );
+}
+
+void CNetwork::RemoveListener( CNetworkListner *listener )
+{
+ allListeners.Remove(listener);
+}
+
+void CNetwork::SetPromiscuousMode( bool enabled )
+{
+ promiscuous = enabled;
+}
+
+bool CNetwork::LoadConfig( char *szConfigXml )
+{
+ uint32_t len = strlen(szConfigXml);
+ if( NULL == szConfigXml || 0 == len)
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Path to config file was NULL"RESETCOLOR"\n" );
+ return false;
+ }
+ if ('/' == szConfigXml[0])
+ {
+ char path[300];
+ uint32_t i;
+ uint32_t lastSlash = 0;
+ for (i = len - 1; i > 0; i--)
+ {
+ if ('/' == szConfigXml[i])
+ {
+ lastSlash = i;
+ break;
+ }
+ }
+ memcpy(path, szConfigXml, lastSlash);
+ path[lastSlash] = '\0';
+ memcpy(szConfigXml, &szConfigXml[lastSlash + 1], (len - lastSlash - 1) );
+ szConfigXml[len - lastSlash - 1] = '\0';
+ return LoadConfig(szConfigXml, path);
+ }
+ else
+ {
+ return LoadConfig(szConfigXml, NULL);
+ }
+}
+
+bool CNetwork::LoadConfig( const char *szConfigXml, const char *szSearchPath )
+{
+ char configPath[300];
+ if( NULL == szConfigXml || 0 == strlen(szConfigXml))
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Path to config file was NULL"RESETCOLOR"\n" );
+ return false;
+ }
+ if (NULL != szSearchPath)
+ strncpy( searchPath, szSearchPath, sizeof( searchPath ) );
+ if( NULL != searchPath && '/' != szConfigXml[0])
+ snprintf( configPath, sizeof( configPath ), "%s/%s", searchPath, szConfigXml );
+ else
+ strncpy( configPath, szConfigXml, sizeof( configPath ) );
+
+ allowNetworkRun = true;
+
+ sem_wait( &vodXmlMutex );
+ bool success;
+ if( NULL != vodXml )
+ {
+ delete vodXml;
+ }
+ vodXml = new CVodXml( configPath );
+ success = ( NULL != vodXml );
+ sem_post( &vodXmlMutex );
+
+ if ( allNetworkDevices.Size() != 0 )
+ {
+ bool tm;
+ uint32_t bw;
+ if (vodXml->GetMostParameters( &tm, &bw ) )
+ {
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ allNetworkDevices[i]->SetAsyncBandwidth(bw);
+ allNetworkDevices[i]->SetTimingMaster(tm);
+ ShutdownMost(allNetworkDevices[i]);
+ }
+ }
+ }
+
+ if( success )
+ FindNewNetworkDevices();
+
+ retryCounter = 0;
+ return success;
+}
+
+bool CNetwork::ActionsPending()
+{
+ bool isPending = false;
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ if( allNetworkDevices[i]->ActionsPending() )
+ {
+ isPending = true;
+ break;
+ }
+ }
+ return isPending;
+}
+
+bool CNetwork::ConnectSourceToSink( CMacAddr *SourceMacAddr, TChannelId SourceChannelId, CMacAddr *SinkMacAddr,
+ TChannelId SinkChannelId )
+{
+ CNodeEntry *inNode = CNodeEntry::GetNodeEntry( SourceMacAddr );
+ CNodeEntry *outNode = CNodeEntry::GetNodeEntry( SinkMacAddr );
+ return ConnectSourceToSink( inNode, outNode, SourceChannelId, SinkChannelId );
+}
+
+uint8_t CNetwork::GetAmountOfLocalNodes()
+{
+ return allNetworkDevices.Size();
+}
+
+bool CNetwork::SendMostControlMessage( TMostInstace mostInstance, uint32_t targetAddr, uint32_t nFBlock,
+ uint32_t nInst, uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload )
+{
+ bool success = false;
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ if( allNetworkDevices[i]->GetDeviceIndex() == mostInstance )
+ {
+ if (targetAddr < 0x300 || targetAddr > 0x3FF || targetAddr == 0x3C8)
+ {
+ success = allNetworkDevices[i]->SendMostControlMessage( mostInstance, targetAddr, nFBlock, nInst, nFunc,
+ nOpType, nPayloadLen, Payload );
+ }
+ else
+ {
+ success = true;
+ for (uint16_t j = 0; j < CNodeEntry::GetAmountOfNodeEntries(); j++)
+ {
+ CNodeEntry *node = CNodeEntry::GetNodeEntry(j);
+ if (NULL != node && node->deviceInstance == mostInstance &&
+ node->deviceType == targetAddr)
+ {
+ success &= allNetworkDevices[i]->SendMostControlMessage( mostInstance, node->nodeAddress, nFBlock, nInst, nFunc,
+ nOpType, nPayloadLen, Payload );
+ }
+ }
+ }
+ break;
+ }
+ }
+ return success;
+}
+
+bool CNetwork::SendMostControlMessage( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst,
+ uint32_t nFBlock, uint32_t nInst, uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload )
+{
+ bool success = false;
+
+ CNodeEntry *entry = CNodeEntry::GetNodeEntry( mostInstance, deviceId, devInst );
+ if( NULL == entry )
+ return success;
+
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ if( allNetworkDevices[i]->GetDeviceIndex() == mostInstance )
+ {
+ success = allNetworkDevices[i]->SendMostControlMessage( mostInstance, entry->nodeAddress, nFBlock, nInst,
+ nFunc, nOpType, nPayloadLen, Payload );
+ break;
+ }
+ }
+ return success;
+}
+
+bool CNetwork::ExecuteXmlScriptFromFile( TMostInstace mostInstance, uint32_t targetAddr, const char *szFile )
+{
+ if (NULL == szFile)
+ return false;
+ bool success = false;
+ char scriptPath[300];
+ const char *pPath = szFile;
+ if( NULL != searchPath && '/' != szFile[0])
+ {
+ snprintf( scriptPath, sizeof( scriptPath ), "%s/%s", searchPath, szFile );
+ pPath = scriptPath;
+ }
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ if( allNetworkDevices[i]->GetDeviceIndex() == mostInstance )
+ {
+ allNetworkDevices[i]->ExecuteMcmScript( targetAddr, pPath );
+ success = true;
+ break;
+ }
+ }
+ return success;
+}
+
+bool CNetwork::ExecuteXmlScriptFromFile( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst,
+ const char *szFile )
+{
+ CNodeEntry *entry = CNodeEntry::GetNodeEntry( mostInstance, deviceId, devInst );
+ if( NULL == entry )
+ return false;
+
+ return ExecuteXmlScriptFromFile( mostInstance, entry->nodeAddress, szFile );
+}
+
+bool CNetwork::ExecuteXmlScriptFromMemory( TMostInstace mostInstance, uint32_t targetAddr, const char *szBuffer,
+ uint32_t nBufferLen )
+{
+ bool success = false;
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ if( allNetworkDevices[i]->GetDeviceIndex() == mostInstance )
+ {
+ allNetworkDevices[i]->ExecuteMcmScript( targetAddr, szBuffer, nBufferLen );
+ success = true;
+ break;
+ }
+ }
+ return success;
+}
+
+bool CNetwork::ExecuteXmlScriptFromMemory( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst,
+ const char *szBuffer, uint32_t nBufferLen )
+{
+ CNodeEntry *entry = CNodeEntry::GetNodeEntry( mostInstance, deviceId, devInst );
+ if( NULL == entry )
+ return false;
+
+ return ExecuteXmlScriptFromMemory( mostInstance, entry->nodeAddress, szBuffer, nBufferLen );
+}
+
+uint32_t CNetwork::GetCounterPartOfRoute( const Route_t *pInRoute, Route_t **pOutRouteArray )
+{
+ if( ( NULL == pInRoute ) || ( NULL == pOutRouteArray ) )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"GetCounterPartOfRoute was called with wrong parameters"RESETCOLOR"\n" );
+ return 0;
+ }
+ *pOutRouteArray = NULL;
+ CSafeVector<CRouteTerminal *> connectedTerminals;
+ CRouteTerminal terminal;
+ terminal.deviceType = pInRoute->deviceType;
+ terminal.instance = pInRoute->instance;
+ terminal.channelId = pInRoute->channelId;
+
+ sem_wait( &vodXmlMutex );
+ bool found = vodXml->GetRouteTerminals( &terminal, connectedTerminals );
+ sem_post( &vodXmlMutex );
+ if( !found )
+ return 0;
+ uint32_t arrayLen = connectedTerminals.Size();
+ *pOutRouteArray = ( Route_t * )calloc( arrayLen, sizeof( Route_t ) );
+ if( NULL == *pOutRouteArray )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"GetCounterPartOfRoute failed to allocate memory"RESETCOLOR"\n" );
+ return 0;
+ }
+ for( uint32_t i = 0; i < arrayLen; i++ )
+ {
+ ( *pOutRouteArray )[i].deviceType = connectedTerminals[i]->deviceType;
+ ( *pOutRouteArray )[i].instance = connectedTerminals[i]->instance;
+ ( *pOutRouteArray )[i].channelId = connectedTerminals[i]->channelId;
+ }
+ return arrayLen;
+}
+
+bool CNetwork::GetRingBreakDiagnosisResult( TMostInstace mostInstance, uint32_t targetAddr )
+{
+ bool success = false;
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ if( allNetworkDevices[i]->GetDeviceIndex() == mostInstance )
+ {
+ allNetworkDevices[i]->GetRingBreakResultV3( 1, 0 );
+ success = true;
+ break;
+ }
+ }
+ return success;
+}
+
+void CNetwork::EnableMost(bool enabled)
+{
+ allowNetworkRun = enabled;
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ CNetworkDevice *device = allNetworkDevices[i];
+ if (enabled)
+ {
+ if (NetworkState_Available == device->GetNetState())
+ {
+ ConsolePrintf(PRIO_ERROR, RED"MOST is already in NET ON state"RESETCOLOR"\n");
+ return;
+ }
+ device->SetNetstate( NetworkState_Unknown );
+ bool isTimingMaster = device->IsTimingMaster();
+ uint32_t asyncBandwidth = device->GetAsyncBandwidth();
+ if( isTimingMaster )
+ device->MostNetworkStartupV3( 0xFFFF, asyncBandwidth );
+ }
+ else
+ {
+ device->SetNetstate( NetworkState_ShutdownInProgress );
+ device->ClearAllPendingActions();
+ device->MostNetworkShutdownV3();
+ }
+ }
+}
+
+void CNetwork::Run()
+{
+ sleep( 5 );
+ if (retryCounter > 0 && (GetTickCount() - retryExecTime >= 60000))
+ retryCounter = 0;
+ if( allowNetworkRun )
+ FindNewNetworkDevices();
+}
+
+/*---------------------------------------------*/
+/* Empty implementation of CNetworkListner */
+/*---------------------------------------------*/
+
+void CNetworkListner::OnNetworkState( uint8_t mostInstance, bool available, uint8_t maxPos, uint16_t packetBW )
+{
+ ConsolePrintf( PRIO_LOW, "CNetwork::OnNetworkState\n" );
+}
+
+void CNetworkListner::OnChannelAvailable( CMacAddr *macAddr, TDeviceId deviceId, uint8_t devInst, TChannelId channelId,
+ TMostInstace mostInstance, EPDataType_t dataType, TBlockwidth reservedBandwidth, bool isSourceDevice,
+ bool inSocketCreated, bool outSocketCreated, bool socketsConnected, int32_t bufferSize,
+ uint32_t mostConnectionLabel, int16_t splittedOffset, int16_t splittedMaxBandwidth, uint16_t packetsPerXact,
+ const char *deviceName )
+{
+ ConsolePrintf( PRIO_LOW, "CNetwork::OnCharacterDeviceAvailable(%s)\n", deviceName );
+}
+
+void CNetworkListner::OnChannelUnavailable( CMacAddr *macAddr, TChannelId channelId, uint8_t mostInstance )
+{
+ ConsolePrintf( PRIO_LOW, "CNetwork::OnChannelUnavailable\n" );
+}
+
+void CNetworkListner::OnMostControlMessage( uint8_t devInst, 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 )
+{
+ ConsolePrintf( PRIO_LOW, "CNetwork::OnMostControlMessage\n" );
+}
+
+void CNetworkListner::OnRingBreakDiagnosisResultV3( uint8_t devInst, uint16_t nodeAddress, uint8_t result,
+ uint8_t position, uint8_t status, uint16_t id )
+{
+ ConsolePrintf( PRIO_LOW, "CNetwork::OnRingBreakDiagnosisResultV2\n" );
+}
diff --git a/Src/Network/Network.h b/Src/Network/Network.h
new file mode 100644
index 0000000..749e903
--- /dev/null
+++ b/Src/Network/Network.h
@@ -0,0 +1,498 @@
+/*
+ * 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 CNetworkListner class.
+ */
+/*----------------------------------------------------------*/
+#ifndef _NETWORK_H_
+#define _NETWORK_H_
+
+#include "SafeVector.h"
+#include "Types.h"
+#include "Thread.h"
+#include "MacAddr.h"
+#include "NetworkDevice.h"
+#include "NetworkDeviceListener.h"
+#include "VodXml.h"
+
+/*----------------------------------------------------------*/
+/*! \brief CNetworkListner class shall be derived from classes, which want them self to be registered as callback to the CNetwork class.
+ */
+/*----------------------------------------------------------*/
+class CNetworkListner
+{
+public:
+ /*----------------------------------------------------------*/
+ /*! \brief This callback method is called whenever there is a new channel information available.
+ * \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
+ * \param mostInstance - The instance number of the MOST bus. If the server device has more then one physical MOST devices, each ring
+ * is identified by a unique id starting with 0 for the first MOST instance.
+ * \param available - true, if the network is fully usable. false, otherwise.
+ * \param maxPos - The amount of devices found in the network (inclusive master)
+ * \param packetBW - Amount of bytes reserved for Ethernet data (multiple with 48000 to get Byte/s)
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnNetworkState( uint8_t mostInstance, bool available, uint8_t maxPos, uint16_t packetBW );
+
+ /*----------------------------------------------------------*/
+ /*! \brief This callback method is called whenever there is a new channel information available.
+ * \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
+ * \param macAddr - The MAC address identifying the device unique.
+ * \param deviceId - The device identifier (group address) as specified in the XML file.
+ * \param devInst - The instance number of the device. Starting with 0 for the first device with deviceId.
+ * \param channelId - The channel identifier as specified in the XML file, given by "LoadConfig"-method of CNetwork class.
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring.
+ * \param dataType - The MOST data used by this channel.
+ * \param reservedBandwidth - The reserved MOST bandwidth in bytes for this channel.
+ * is identified by a unique id starting with 0 for the first MOST instance.
+ * \param isSourceDevice - true, if this device acts as source. false, if this device acts as sink.
+ * \param inSocketCreated - true, if the in-socket of the connection was created. false, there is no in-socket available at the moment.
+ * \param outSocketCreated - true, if the out-socket of the connection was created. false, there is no out-socket available at the moment.
+ * \param socketsConnected - true, if the in- and the out-socket are connected.
+ * \param splittedOffset - If this socket is a splitted / combined socket, this value holds the offset in byte. -1 if this is a normal socket.
+ * \param splittedMaxBandwidth - If this socket is a splitted / combined socket, this value holds the maximum bandwidth of all splitted sockets in byte. -1 if this is a normal socket.
+ * \param bufferSize - The amount of bytes reserved for this channel in Driver. If no buffers were allocated, this value is -1.
+ * \param packetsPerXactconst, This is USB specific. It describes how many sub-frames are concatenated into a single USB microframe.
+ * \param deviceName - The name of the Linux character device. May be NULL if the device is a remote device.
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnChannelAvailable( CMacAddr *macAddr, TDeviceId deviceId, uint8_t devInst, TChannelId channelId,
+ TMostInstace mostInstance, EPDataType_t dataType, TBlockwidth reservedBandwidth, bool isSourceDevice,
+ bool inSocketCreated, bool outSocketCreated, bool socketsConnected, int32_t bufferSize,
+ uint32_t mostConnectionLabel, int16_t splittedOffset, int16_t splittedMaxBandwidth,
+ uint16_t packetsPerXact, const char *deviceName );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief This callback method is called whenever a channel has become unavailable.
+ * \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
+ * \param macAddr - The MAC address identifying the device unique.
+ * \param channelId - The channel identifier as specified in the XML file, given by "LoadConfig"-method of CNetwork class.
+ * \param mostInstance - The instance number of the MOST bus. If the server device has more then one physical MOST devices, each ring
+ * is identified by a unique id starting with 0 for the first MOST instance.
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnChannelUnavailable( CMacAddr *macAddr, TChannelId channelId, uint8_t mostInstance );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief This callback method is called whenever a MOST control message was sent or received.
+ * \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
+ * \note The user may interpret the data and sent a corresponding MOST control message via CNetwork::SendMostControlMessage.
+ * \param devInst - The MOST ring instance, starting with 0 for the first MOST ring.
+ * \param sourceAddr - The MOST source address (may be not accurate)
+ * \param targetAddr - The MOST target address
+ * \param nFBlock - The MOST Function Block Identifier
+ * \param nInst - The MOST Function Block Instance Identifier
+ * \param nFunc - The MOST Function Block Function Identifier
+ * \param nPayloadLen - The amount of bytes stored in Payload
+ * \param Payload - The pointer to the payload byte array.
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnMostControlMessage( uint8_t devInst, 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 );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when a Ring Break Diagnosis Result was received.
+ * \param devInst - The MOST ring instance, starting with 0 for the first MOST ring.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \praram result - The ring break diagnosis result
+ * \param position - Relative position to the ring break.
+ * \param status - Gives information about the activity state.
+ * \param id - The RBD identifier as configured in config string.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnRingBreakDiagnosisResultV3( uint8_t devInst, uint16_t nodeAddress, uint8_t result,
+ uint8_t position, uint8_t status, uint16_t id );
+};
+
+/*----------------------------------------------------------*/
+/*! \brief CNetwork represents the main controlling class, which opens and setup MOST connections.
+*/
+/*----------------------------------------------------------*/
+class CNetwork : public CNetworkDeviceListener, public CThread
+{
+
+private:
+ bool allowNetworkRun;
+ char searchPath[256];
+ CSafeVector<CNetworkListner *> allListeners;
+ static CSafeVector<CNetworkDevice *> allNetworkDevices;
+ CVodXml *vodXml;
+ sem_t vodXmlMutex;
+ uint32_t connectionBitMask;
+ bool promiscuous;
+ uint32_t retryCounter;
+ uint32_t retryExecTime;
+
+ CNetwork();
+
+ void DestroyAllResources( CNetworkDevice *device, uint16_t nodeAddress );
+
+ void CloseAllNetworkDevices();
+
+ void DestroyAllResources();
+
+ void FindNewNetworkDevices();
+
+ void TryToCreateRoute( uint32_t devInstance, bool mostIsTx, void *entry, void *terminal );
+
+ void TryToConnectSockets( uint32_t devInstance, uint16_t nodeAddr, uint32_t channelId );
+
+ void TryToCloseExistingMostConnection( void *inNode, uint32_t channelId, void *outNode, uint32_t outChannelId );
+
+ void RaiseAvailable( void *connection );
+
+ void RaiseUnavailable( void *connection );
+
+ CNetworkDevice *GetNetworkDevice( uint32_t devInstance );
+
+ CMacAddr *SetMacAddress( CNetworkDevice *device, uint32_t devInstance, uint16_t nodeAddress,
+ uint8_t inicApiVersion );
+
+ bool ConnectSourceToSink( void *mostTxNode, void *mostRxNode, uint32_t sourceChannelId, uint32_t sinkChannelId );
+
+ void RaiseUknownConnection( uint32_t devInstance, uint16_t nodeAddress, EPDataType_t dType );
+
+ void ShutdownMost( CNetworkDevice *device );
+
+ void ShutdownMostBecauseOfErrors( CNetworkDevice *device );
+
+ virtual void OnSync( void *source, bool isSynced );
+
+ virtual void 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 );
+
+ virtual void OnNetworkStartupV3( void *source, bool success );
+
+ virtual void OnNetworkShutdownV3( void *source, bool success );
+
+ virtual void OnMostDeviceType( void *source, bool success, uint16_t nodeAddress, uint16_t deviceType );
+
+ virtual void 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 );
+
+ virtual void 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 );
+
+ virtual void 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 );
+
+ virtual void OnConnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t inSocketHandle,
+ uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag );
+
+ virtual void OnDestroySocketV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag );
+
+ virtual void OnDisconnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag );
+
+ virtual void OnCreateI2SSocketV1( void *source, bool success, uint16_t nodeAddr, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V1I2SPin_t pin, uint16_t socketHandle, uint32_t tag );
+
+ virtual void OnCreateUsbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
+ EPDirection_t epDir, uint8_t endPointAddress, uint16_t socketHandle, uint32_t tag );
+
+ virtual void 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 );
+
+ virtual void 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 );
+
+ virtual void 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 );
+
+ virtual void 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 );
+
+ virtual void 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 );
+
+ virtual void 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 );
+
+ virtual void OnConnectSocketsV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
+ uint16_t inSocketHandle, uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag );
+
+ virtual void OnControlChannelReadEnd( void *source );
+
+ virtual void 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 );
+
+ virtual void OnRbdResultV3( void *source, uint16_t nodeAddress, uint8_t result, uint8_t position,
+ uint8_t status, uint16_t id );
+
+ virtual void 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 );
+
+ virtual void OnConfigureI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
+ V3I2SPortOption_t option, V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag );
+
+ virtual void OnCreateI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
+ V3I2SPortSpeed_t clock, V3I2SAlignment_t align, uint32_t tag );
+
+ virtual void 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 );
+public:
+ /*----------------------------------------------------------*/
+ /*! \brief Destructor of CNetwork.
+ */
+ /*----------------------------------------------------------*/
+ virtual ~CNetwork();
+
+
+
+ //Singleton pattern, there can only be one manager
+ /*----------------------------------------------------------*/
+ /*! \brief Gets the singleton instance of CNetwork (Only one object).
+ * \return Pointer to the singleton object.
+ */
+ /*----------------------------------------------------------*/
+ static CNetwork *GetInstance( void );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Registers the given CNetworkListener to this component.
+ * If there are events, all registered listeners will be called back.
+ * \note Multiple listerners are supported.
+ * \param listener- Class derivating CNetworkListener base class. This class will be called back on events.
+ */
+ /*----------------------------------------------------------*/
+ void AddListener( CNetworkListner *listener );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Deregisters the given CNetworkListener from this component.
+ * The given object will no longer be called back.
+ * \param listener- Class derivating CNetworkListener base class. This class will not be called after this method call.
+ */
+ /*----------------------------------------------------------*/
+ void RemoveListener( CNetworkListner *listener );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Enables or Disables the promiscuous mode on MEP channel. If enabled, tools like Wireshark will capture every packet.
+ * \param enabled - true, promiscuous mode. false, perfect match filter with multicast and broadcast enabled.
+ */
+ /*----------------------------------------------------------*/
+ void SetPromiscuousMode( bool enabled );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Loads a XML file holding information about connections and devices.
+ * \param szConfigXml - string holding only the filename to the XML file.
+ * \note This method tries to extract the search path from the given string. Therefor it must start with '/'.
+ * \note The given string will be modified by this method. Don't use it anymore after wise!
+ * \return true, if successful, false otherwise
+ */
+ /*----------------------------------------------------------*/
+ bool LoadConfig( char *szConfigXml );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Loads a XML file holding information about connections and devices.
+ * \param szConfigXml - string holding only the filename to the XML file.
+ * \param szSearchPath - string holding the path to all the XML files.
+ * \return true, if successful, false otherwise
+ */
+ /*----------------------------------------------------------*/
+ bool LoadConfig( const char *szConfigXml, const char *szSearchPath );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Checks if there are pending actions enqueued.
+ * \note This method blocks, until the result (true / false is reported by the subprocess).
+ * \return true, when there are pending actions in the queue. false, otherwise
+ */
+ /*----------------------------------------------------------*/
+ bool ActionsPending();
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Connects a source to sink according to the configuration of the XML file, provided by LoadConfig method.
+ * \param SourceMacAddr - The MAC address of the source device, reported by the OnChannelAvailable callback method.
+ * \param SourceChannelId - The channel identifier of the source as specified in the XML file and reported by
+ * the OnChannelAvailable callback method.
+ * \param SinkMacAddr - The MAC address of the sink device, reported by the OnChannelAvailable callback method.
+ * \param SourceChannelId - The channel identifier of the sink as specified in the XML file and reported by
+ * the OnChannelAvailable callback method.
+ * \return true, if succesful. false, otherwise
+ */
+ /*----------------------------------------------------------*/
+ bool ConnectSourceToSink( CMacAddr *SourceMacAddr, TChannelId SourceChannelId, CMacAddr *SinkMacAddr,
+ TChannelId SinkChannelId );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retrieves the amount of connected INIC nodes.
+ * \return The amount of local connected INIC nodes.
+ */
+ /*----------------------------------------------------------*/
+ uint8_t GetAmountOfLocalNodes();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Sends the given Control Message out to the given MOST ring
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
+ * \param targetAddr - The MOST target address (0x100, 0x401, etc..)
+ * \param nFBlock - The MOST Function Block Identifier
+ * \param nInst - The MOST Function Block Instance Identifier
+ * \param nFunc - The MOST Function Block Function Identifier
+ * \param nPayloadLen - The amount of bytes stored in Payload
+ * \param Payload - The pointer to the payload byte array.
+ */
+ /*----------------------------------------------------------*/
+ bool SendMostControlMessage( TMostInstace mostInstance, uint32_t targetAddr, uint32_t nFBlock, uint32_t nInst,
+ uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Sends the given Control Message out to the given MOST ring
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
+ * \param deviceId - The device identifier (group address) as specified in the XML file
+ * \param devInst - The instance number of the device. Starting with 0 for the first device with deviceId
+ * \param nFBlock - The MOST Function Block Identifier
+ * \param nInst - The MOST Function Block Instance Identifier
+ * \param nFunc - The MOST Function Block Function Identifier
+ * \param nPayloadLen - The amount of bytes stored in Payload
+ * \param Payload - The pointer to the payload byte array.
+ */
+ /*----------------------------------------------------------*/
+ bool SendMostControlMessage( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst, uint32_t nFBlock,
+ uint32_t nInst, uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Executes a given XML script by it's filename and MOST target address
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
+ * \param targetAddr - The MOST target address (0x100, 0x401, etc..)
+ * \param szFile - Path to the XML file (zero terminated string)
+ */
+ /*----------------------------------------------------------*/
+ bool ExecuteXmlScriptFromFile( TMostInstace mostInstance, uint32_t targetAddr, const char *szFile );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Executes a given XML script by it's filename, device identifier and device instance
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
+ * \param deviceId - The device identifier (group address) as specified in the XML file
+ * \param devInst - The instance number of the device. Starting with 0 for the first device with deviceId
+ * \param szFile - Path to the XML file (zero terminated string)
+ */
+ /*----------------------------------------------------------*/
+ bool ExecuteXmlScriptFromFile( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst,
+ const char *szFile );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Executes a given XML script directly by it's content stored in the memory and MOST target address
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
+ * \param targetAddr - The MOST target address (0x100, 0x401, etc..)
+ * \param szBuffer - The Buffer containing the XML script
+ * \param nBufferLen - The length of the XML script stored in szBuffer
+ */
+ /*----------------------------------------------------------*/
+ bool ExecuteXmlScriptFromMemory( TMostInstace mostInstance, uint32_t targetAddr, const char *szBuffer,
+ uint32_t nBufferLen );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Executes a given XML script by it's filename, device identifier and device instance
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
+ * \param targetAddr - The MOST target address (0x100, 0x401, etc..)
+ * \param szBuffer - The Buffer containing the XML script
+ * \param nBufferLen - The length of the XML script stored in szBuffer
+ */
+ /*----------------------------------------------------------*/
+ bool ExecuteXmlScriptFromMemory( TMostInstace mostInstance, TDeviceId deviceId, uint8_t devInst,
+ const char *szBuffer, uint32_t nBufferLen );
+
+ /*!
+ * \brief Storage class for channel related informations. This class will be returned by
+ * the CVodXml class.
+ */
+ typedef struct
+ {
+ /// Determines the device type as specified in the configuration XML file and found in the group address configuration.
+ uint32_t deviceType;
+
+ /// instance number of the device found in the network
+ uint32_t instance;
+
+ /// Determines the used channel id, as specified in the configuration XML file.
+ uint32_t channelId;
+ } Route_t;
+
+ /*----------------------------------------------------------*/
+ /*! \brief Sends the given Control Message out to the given MOST ring.
+ * \param pInRoute - Pointer to the route to search the counter part of.
+ * \param pOutRouteArray - Pointer to pointer, which then the result array will be stored, maybe NULL!
+ * \return The array length of pOutRouteArray, maybe 0!
+ * \note The pOutRouteArray must be freed by the user after usage!
+ */
+ /*----------------------------------------------------------*/
+ uint32_t GetCounterPartOfRoute( const Route_t *pInRoute, Route_t **pOutRouteArray );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retrieves the stored result of the Ring Break Diagnosis
+ * \param mostInstance - The MOST ring instance, starting with 0 for the first MOST ring
+ * \param targetAddr - The MOST target address (0x100, 0x401, etc..)
+ * \return true, if successful, false otherwise
+ */
+ /*----------------------------------------------------------*/
+ bool GetRingBreakDiagnosisResult( TMostInstace mostInstance, uint32_t targetAddr );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Enables or disables all MOST rings.
+ * \note This is thought for debug reasons only. Normally this method must not be called.
+ * \param enabled - TRUE, all MOST rings will start up. FALSE, all MOST rings will shutdown.
+ */
+ /*----------------------------------------------------------*/
+ void EnableMost(bool enabled);
+
+ /*----------------------------------------------------------*/
+ /*! \brief Function of background thread.
+ * \note Never call this method. It is used by internal threads.
+ */
+ /*----------------------------------------------------------*/
+ void Run();
+
+};
+
+
+#endif
diff --git a/Src/Network/NetworkDevice.cpp b/Src/Network/NetworkDevice.cpp
new file mode 100644
index 0000000..5308215
--- /dev/null
+++ b/Src/Network/NetworkDevice.cpp
@@ -0,0 +1,903 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include "NetworkDevice.h"
+#include "DriverConfiguration.h"
+#include "Board.h"
+#include "ScriptXml.h"
+#include "IndustrialStack_ApiV1.h"
+#include "IndustrialStack_ApiV3.h"
+#include "IndustrialStack_ApiGeneric.h"
+
+CNetworkDevice::CNetworkDevice( uint8_t index, uint8_t api, bool master, uint32_t asyncBW, bool promiscuousMode ) :
+CThread( "CNetworkDevice", false ), promiscuous( promiscuousMode ), netState( NetworkState_Unknown ),
+ pInic( NULL ), pScriptMemoryArea( NULL ), isRunning( false ),
+ isActionPending( false ), deviceIndex( index ), deviceApi( api ),
+ isTimingMaster( master ), asyncBandwidth( asyncBW ),
+ controlEndpointRxHandle( -1 ), controlEndpointTxHandle( -1 ),
+ startV3autoForced( 0xFFFF ), startV3packetBW( 0xFFFF )
+{
+ responseToWaitFor[0] = '\0';
+ deviceNameControlRx[0] = '\0';
+ deviceNameControlTx[0] = '\0';
+
+ sem_init( &methodMutex, 0, 0 ); //Mutex, initialized to 0 => sem_wait will block
+}
+
+CNetworkDevice::~CNetworkDevice()
+{
+ Stop();
+ CloseMostControlChannel();
+ if (NULL != iStack)
+ {
+ delete iStack;
+ iStack = NULL;
+ }
+ if (NULL != v1Events)
+ {
+ delete v1Events;
+ v1Events = NULL;
+ }
+ if (NULL != v3Events)
+ {
+ delete v3Events;
+ v3Events = NULL;
+ }
+}
+
+bool CNetworkDevice::OpenDevice( const char *systemNameControlRx, const char *systemNameControlTx,
+ const char *linkNameControlRx, const char *linkNameControlTx )
+{
+ ConsolePrintf( PRIO_LOW, "SYS RX:%s\nSYS TX:%s\nLINK RX:%s\nLINK TX:%s\n", systemNameControlRx,
+ systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ CloseMostChannel( systemNameControlRx );
+ CloseMostChannel( systemNameControlTx );
+
+ bool success = ConfigureMostChannel( systemNameControlRx, EP_Control, EPDIR_OUT, 32, 128 );
+
+ if( success )
+ {
+ success = ConfigureMostChannel( systemNameControlTx, EP_Control, EPDIR_IN, 32, 128 );
+ }
+
+ if( success )
+ {
+ success = LinkToCharacterDevice( linkNameControlRx, deviceNameControlRx );
+ }
+
+ if( success )
+ {
+ success = LinkToCharacterDevice( linkNameControlTx, deviceNameControlTx );
+ }
+
+ if( success )
+ {
+ if( OpenMostControlChannel() )
+ {
+ isRunning = true;
+ Start();
+ }
+ else
+ {
+ ConsolePrintf( PRIO_ERROR, RED"MOST control channel startup failed"RESETCOLOR"\n" );
+ }
+
+ }
+ else
+ {
+ ConsolePrintf(
+ PRIO_ERROR, RED"NetworkDevice: Open device aborted, because of channel configuration issues"RESETCOLOR"\n" );
+ }
+ return success;
+}
+
+bool CNetworkDevice::OpenUsb( uint8_t controlRxEndpointAddress, uint8_t controlTxEndpointAddress )
+{
+ char systemNameControlRx[64];
+ char systemNameControlTx[64];
+ char linkNameControlRx[64];
+ char linkNameControlTx[64];
+ bool success = GetUsbDeviceNames( deviceIndex, controlRxEndpointAddress,
+ deviceNameControlRx, sizeof( deviceNameControlRx ), systemNameControlRx, sizeof( systemNameControlRx ),
+ linkNameControlRx, sizeof( linkNameControlRx ) );
+
+ if( success )
+ success = GetUsbDeviceNames( deviceIndex, controlTxEndpointAddress,
+ deviceNameControlTx, sizeof( deviceNameControlTx ), systemNameControlTx, sizeof( systemNameControlTx ),
+ linkNameControlTx, sizeof( linkNameControlTx ) );
+
+ if( success )
+ success = OpenDevice( systemNameControlRx, systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ if( ! success )
+ ConsolePrintf( PRIO_ERROR, RED"NetworkDevice: Failed to open USB device"RESETCOLOR"\n" );
+
+ return success;
+}
+
+bool CNetworkDevice::OpenMlb( uint8_t controlRxChannelAddress, uint8_t controlTxChannelAddress )
+{
+ char systemNameControlRx[64];
+ char systemNameControlTx[64];
+ char linkNameControlRx[64];
+ char linkNameControlTx[64];
+ bool success = GetMlbDeviceNames( deviceIndex, controlRxChannelAddress,
+ deviceNameControlRx, sizeof( deviceNameControlRx ), systemNameControlRx, sizeof( systemNameControlRx ),
+ linkNameControlRx, sizeof( linkNameControlRx ) );
+
+ if( success )
+ success = GetMlbDeviceNames( deviceIndex, controlTxChannelAddress,
+ deviceNameControlTx, sizeof( deviceNameControlTx ), systemNameControlTx, sizeof( systemNameControlTx ),
+ linkNameControlTx, sizeof( linkNameControlTx ) );
+
+ if( success )
+ success = OpenDevice( systemNameControlRx, systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ if( ! success )
+ ConsolePrintf( PRIO_ERROR, RED"NetworkDevice: Failed to open MLB device"RESETCOLOR"\n" );
+
+ return success;
+}
+
+bool CNetworkDevice::OpenI2C()
+{
+ char systemNameControlRx[64];
+ char systemNameControlTx[64];
+ char linkNameControlRx[64];
+ char linkNameControlTx[64];
+ bool success = GetI2CDeviceNames( deviceIndex, false, deviceNameControlRx, sizeof( deviceNameControlRx ),
+ systemNameControlRx, sizeof( systemNameControlRx ), linkNameControlRx, sizeof( linkNameControlRx ) );
+
+ if( success )
+ success = GetI2CDeviceNames( deviceIndex, true, deviceNameControlTx, sizeof( deviceNameControlTx ),
+ systemNameControlTx, sizeof( systemNameControlTx ), linkNameControlTx, sizeof( linkNameControlTx ) );
+
+ if( success )
+ success = OpenDevice( systemNameControlRx, systemNameControlTx, linkNameControlRx, linkNameControlTx );
+
+ if( ! success )
+ ConsolePrintf( PRIO_ERROR, RED"NetworkDevice: Failed to open I2C device"RESETCOLOR"\n" );
+
+ return success;
+}
+
+void CNetworkDevice::Close()
+{
+ int32_t timeoutVal = 10; //10 Seconds
+ while( timeoutVal-- > 0 )
+ {
+ if( iStack->ElementsPending() )
+ {
+ ConsolePrintf( PRIO_MEDIUM, "NetworkDevice: Closing delayed, Actions pending..\n" );
+ usleep( 1000000 );
+ }
+ else
+ {
+ break;
+ }
+ }
+ sem_post( &methodMutex );
+ isRunning = false;
+ Stop();
+ for( uint32_t timeout = 0; timeout < 100; timeout++ )
+ {
+ if( !IsThreadRunning() )
+ break;
+ usleep( 10000 );
+ }
+ ConsolePrintf( PRIO_LOW, "NetworkDevice: Closed..\n" );
+}
+
+uint8_t CNetworkDevice::GetDeviceApi()
+{
+ return deviceApi;
+}
+
+NetworkState_t CNetworkDevice::GetNetState()
+{
+ return netState;
+}
+
+void CNetworkDevice::SetNetstate( NetworkState_t newState )
+{
+ netState = newState;
+}
+
+ void CNetworkDevice::SetTimingMaster(bool tm)
+ {
+ isTimingMaster = tm;
+ }
+
+bool CNetworkDevice::IsTimingMaster()
+{
+ return isTimingMaster;
+}
+
+void CNetworkDevice::SetAsyncBandwidth(uint32_t bw)
+{
+ asyncBandwidth = bw;
+}
+
+uint32_t CNetworkDevice::GetAsyncBandwidth()
+{
+ return asyncBandwidth;
+}
+
+bool CNetworkDevice::ActionsPending()
+{
+ if( NULL == iStack || !isRunning )
+ return true;
+ return iStack->ElementsPending();
+}
+
+void CNetworkDevice::ClearAllPendingActions()
+{
+ if( NULL == iStack )
+ return;
+ iStack->ClearAllElements();
+}
+
+void CNetworkDevice::AddListener( CNetworkDeviceListener *listener )
+{
+ allListeners.PushBack( listener );
+}
+
+uint32_t CNetworkDevice::GetAmountOfListners()
+{
+ return allListeners.Size();
+}
+
+CNetworkDeviceListener *CNetworkDevice::GetListener( uint32_t instance )
+{
+ return allListeners[instance];
+}
+
+uint8_t CNetworkDevice::GetDeviceIndex()
+{
+ return deviceIndex;
+}
+
+void CNetworkDevice::ScriptPause( uint32_t timeInMillis )
+{
+ CISWaitElement *waitElement = new CISWaitElement();
+ waitElement->SetTimeout(timeInMillis);
+ iStack->EnqueueElement(0x1, waitElement);
+ waitElement->RemoveReference();
+}
+
+void CNetworkDevice::ExecuteMcmScript( uint16_t nodeAddress, CSciptXml *scriptXml )
+{
+ if( NULL == scriptXml )
+ {
+ ConsolePrintf(
+ PRIO_ERROR, RED"ExecuteMcmScript failed to retrieve scripts from XML file"RESETCOLOR"\n" );
+ return;
+ }
+ CSafeVector<CScript *> allScripts;
+ if( scriptXml->GetScripts( allScripts ) )
+ {
+ for (uint32_t i = 0; i < allScripts.Size(); i++ )
+ {
+ CScript *script = allScripts[i];
+ if( NULL == script )
+ continue;
+ switch( script->scriptType )
+ {
+ case SCRIPT_MCM_SEND:
+ {
+ CGeneric_SendMostMessage *a = new CGeneric_SendMostMessage(
+ script->payload, script->payloadLength, nodeAddress,
+ script->fblockId, 0, script->functionId, script->opTypeRequest,
+ script->opTypeResponse);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+ break;
+ }
+ case SCRIPT_PAUSE:
+ {
+ CISWaitElement *waitElement = new CISWaitElement();
+ waitElement->SetTimeout(script->pauseInMillis);
+ iStack->EnqueueElement(nodeAddress, waitElement);
+ waitElement->RemoveReference();
+ break;
+ }
+ default:
+ ConsolePrintf( PRIO_ERROR,
+ YELLOW"ExecuteMcmScript ignoring unknown script type:%d"RESETCOLOR"\n",
+ script->scriptType );
+ break;
+ }
+ }
+ }
+ allScripts.RemoveAll(true);
+}
+
+void CNetworkDevice::ExecuteMcmScript( uint16_t nodeAddress, const char *pPathToScriptXml )
+{
+ if( NULL == pPathToScriptXml )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"ExecuteMcmScript (from file) was called with invalid parameter"RESETCOLOR"\n" );
+ return;
+ }
+ ConsolePrintf( PRIO_MEDIUM, "##### Executing MCM script from file: Address:%X '%s'\n", nodeAddress,
+ pPathToScriptXml );
+ CSciptXml *scriptXml = new CSciptXml( pPathToScriptXml );
+ ExecuteMcmScript( nodeAddress, scriptXml );
+}
+
+void CNetworkDevice::ExecuteMcmScript( uint16_t nodeAddress, const char *pStringBuffer, uint32_t bufferLength )
+{
+ if( NULL == pStringBuffer || 0 == bufferLength )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"ExecuteMcmScript (from memory) was called with invalid parameter"RESETCOLOR"\n" );
+ return;
+ }
+ ConsolePrintf( PRIO_MEDIUM, "##### Executing MCM script from memory: Address:%X buffer-len:\n", nodeAddress,
+ bufferLength );
+ CSciptXml *scriptXml = new CSciptXml( pStringBuffer, bufferLength );
+ ExecuteMcmScript( nodeAddress, scriptXml );
+}
+
+void CNetworkDevice::ToggleNotOk()
+{
+ CGeneric_SendConfigOk *a = new CGeneric_SendConfigOk(false);
+ iStack->EnqueueElement(0x3C8, a);
+ a->RemoveReference();
+
+ CGeneric_SendConfigOk *b = new CGeneric_SendConfigOk(true);
+ iStack->EnqueueElement(0x3C8, b);
+ b->RemoveReference();
+}
+
+void CNetworkDevice::GetMacAddress( uint16_t nodeAddress )
+{
+ CGeneric_GetMacAddress *a = new CGeneric_GetMacAddress(nodeAddress);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::GetGroupAddresses( uint8_t maxNodePos )
+{
+ for( uint32_t i = 0x400; maxNodePos != 0xFF && i < 0x400 + ( uint32_t )maxNodePos; i++ )
+ {
+ uint16_t n = ( i == 0x400 ? 1 : i );
+ CGeneric_GetGroupAddress *a = new CGeneric_GetGroupAddress(n);
+ iStack->EnqueueElement(n, a);
+ a->RemoveReference();
+ }
+}
+
+void CNetworkDevice::SetMostMacAddressV1( uint16_t nodeAddress, uint8_t macAddress1, uint8_t macAddress2,
+ uint8_t macAddress3, uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6, bool persistent )
+{
+ CV1_ChangeEUI48 *a = new CV1_ChangeEUI48(this, nodeAddress, macAddress1, macAddress2,
+ macAddress3, macAddress4, macAddress5, macAddress6, persistent);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::StartMostV1( bool isTimingMaster, uint16_t packetBandWidth )
+{
+ CV1_NetworkStartup *a = new CV1_NetworkStartup(this, isTimingMaster, packetBandWidth);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkShutdownV1()
+{
+ CISWaitForPendingElements *w = new CISWaitForPendingElements(0x1);
+ iStack->EnqueueElement(0x1, w);
+ w->RemoveReference();
+
+ CV1_NetworkShutdown *a = new CV1_NetworkShutdown(this);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenTsiV1( uint16_t nodeAddress, V1TsiPortInstance_t tsiPortId, V1TsiPortMode tsiPortMode )
+{
+ if (V1TsiPortInstanceNotSet == tsiPortId || V1TsiPortModeNotSet == tsiPortMode)
+ return;
+ CV1_TsiPortCreate *a = new CV1_TsiPortCreate(this, nodeAddress, tsiPortId, tsiPortMode);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateTsiSocketV1( uint16_t nodeAddress, V1TsiPortInstance_t portInst,
+ EPDataType_t epType, EPDirection_t epDir,uint16_t blockWidthTsi, uint32_t tag )
+{
+ CV1_TsiSocketCreate *a = new CV1_TsiSocketCreate(this, nodeAddress, portInst,
+ epType, epDir, blockWidthTsi, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenMlbV1( uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed )
+{
+ if( MlbSpeedNotSet == mlbSpeed )
+ return;
+ CV1_MlbPortCreate *a = new CV1_MlbPortCreate(this, nodeAddress, mlbSpeed);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMlbSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t mlbChannelAddress, uint16_t blockWidthMlb, uint32_t tag )
+{
+ CV1_MlbSocketCreate *a = new CV1_MlbSocketCreate(this, nodeAddress, epType, epDir,
+ mlbChannelAddress, blockWidthMlb, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedMlbSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t mlbChannelAddress, uint16_t blockWidthMlb, uint16_t splittedOffset, uint16_t blockWidthCombined,
+ uint32_t tag )
+{
+ CV1_SplittedMlbSocketCreate *a = new CV1_SplittedMlbSocketCreate(this, nodeAddress,
+ epType, epDir, mlbChannelAddress, blockWidthMlb, splittedOffset, blockWidthCombined, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMostSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t connectionLabel, uint16_t blockWidthMost, uint32_t tag )
+{
+ CV1_MostSocketCreate *a = new CV1_MostSocketCreate(this, nodeAddress,
+ epType, epDir, connectionLabel, blockWidthMost, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ConnectSocketsV1( uint16_t nodeAddress, uint8_t inHandle, uint8_t outHandle, uint32_t tag )
+{
+ CV1_ConnectSockets *a = new CV1_ConnectSockets(this, nodeAddress,
+ inHandle, outHandle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::DestroySocketV1( uint16_t nodeAddress, uint8_t handle, uint32_t tag )
+{
+ CV1_DestroySocket *a = new CV1_DestroySocket(this, nodeAddress, handle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::DisconnectSocketsV1( uint16_t nodeAddress, uint8_t handle, uint32_t tag )
+{
+ CV1_DisconnectSockets *a = new CV1_DisconnectSockets(this, nodeAddress, handle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenStreamPortV1( uint16_t nodeAddress, V1I2SPortClkDriveMode_t portMode,
+ V1I2SStreamingPortMode_t streamPortMode, V1I2SStreamingDataFormat_t format, uint32_t tag )
+{
+ CV1_StreamPortOpen *a = new CV1_StreamPortOpen(this, nodeAddress, portMode, streamPortMode, format, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateStreamSocketV1( uint16_t nodeAddress, EPDirection_t epDir, uint16_t blockWidthI2S,
+ V1I2SPin_t pin, uint32_t tag )
+{
+ CV1_StreamSocketCreate *a = new CV1_StreamSocketCreate(this, nodeAddress, epDir, blockWidthI2S, pin, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedStreamSocketV1( uint16_t nodeAddress, EPDirection_t epDir, uint16_t blockWidthI2S,
+ uint16_t splittedOffset, uint16_t blockWidthCombined, V1I2SPin_t pin, uint32_t tag )
+{
+ CV1_SplittedStreamSocketCreate *a = new CV1_SplittedStreamSocketCreate(this,
+ nodeAddress, epDir, blockWidthI2S, splittedOffset, blockWidthCombined, pin, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::AttachV3()
+{
+ CV3_DeviceAttach *a = new CV3_DeviceAttach();
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::InicUnsychronizeV3()
+{
+ CISWaitForPendingElements *w = new CISWaitForPendingElements(0x1);
+ iStack->EnqueueElement(0x1, w);
+ w->RemoveReference();
+
+ CV3_Unsynchronize *a = new CV3_Unsynchronize();
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::DeviceSyncV3( uint16_t nodeAddress, bool sync )
+{
+ CV3_DeviceSync *a = new CV3_DeviceSync(nodeAddress, sync);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkStartupV3( uint16_t autoForcedNotAvailable, uint16_t packetBW )
+{
+ startV3autoForced = autoForcedNotAvailable;
+ startV3packetBW = packetBW;
+ CV3_NetworkStartup *a = new CV3_NetworkStartup(this, autoForcedNotAvailable, packetBW);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkStartupV3()
+{
+ if( 0xFFFF == startV3packetBW )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Repeated MostNetworkStartupV3 was called"\
+ " without calling the overloaded MostNetworkStartupV3 with parameters"\
+ RESETCOLOR"\n" );
+ return;
+ }
+ CV3_NetworkStartup *a = new CV3_NetworkStartup(this, startV3autoForced, startV3packetBW);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::MostNetworkShutdownV3()
+{
+ CISWaitForPendingElements *w = new CISWaitForPendingElements(0x1);
+ iStack->EnqueueElement(0x1, w);
+ w->RemoveReference();
+
+ CV3_NetworkShutdown *a = new CV3_NetworkShutdown(this);
+ iStack->EnqueueElement(0x1, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::SetMostMacAddressV3( uint16_t nodeAddress, uint8_t macAddress1, uint8_t macAddress2,
+ uint8_t macAddress3, uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6 )
+{
+ CV3_MostNetworkConfiguration *a = new CV3_MostNetworkConfiguration(this, nodeAddress, macAddress1, macAddress2,
+ macAddress3, macAddress4, macAddress5, macAddress6, promiscuous);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::OpenMlbV3( uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed )
+{
+ if( MlbSpeedNotSet == mlbSpeed )
+ return;
+ CV3_MlbPortCreate *a = new CV3_MlbPortCreate(this, nodeAddress, mlbSpeed);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateUsbSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint8_t endPointAddress, uint16_t packetsPerFrame, uint32_t tag )
+{
+ CV3_UsbSocketCreate *a = new CV3_UsbSocketCreate(this, nodeAddress, epType,
+ epDir, endPointAddress, packetsPerFrame, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedUsbSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint8_t endPointAddress, uint16_t packetsPerFrame, uint16_t bytesPerPacket, uint32_t tag )
+{
+ CV3_SplittedUsbSocketCreate *a = new CV3_SplittedUsbSocketCreate(this, nodeAddress,
+ epType, epDir, endPointAddress, packetsPerFrame, bytesPerPacket, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMlbSocketV3( uint16_t nodeAddress, uint16_t mlbPortHandle, EPDataType_t epType,
+ EPDirection_t epDir, uint16_t mlbChannelAddress, uint16_t blockwidthMlb, uint32_t tag )
+{
+ CV3_MlbSocketCreate *a = new CV3_MlbSocketCreate(this, nodeAddress, mlbPortHandle,
+ epType, epDir, mlbChannelAddress, blockwidthMlb, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedMlbSocketV3( uint16_t nodeAddress, uint16_t mlbPortHandle, EPDataType_t epType,
+ EPDirection_t epDir, uint16_t mlbChannelAddress, uint16_t blockwidthMlb, uint16_t bytesPerPacket, uint32_t tag )
+{
+ CV3_SplittedMlbSocketCreate *a = new CV3_SplittedMlbSocketCreate(this, nodeAddress,
+ mlbPortHandle, epType, epDir, mlbChannelAddress, blockwidthMlb, bytesPerPacket, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateMostSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t connectionLabel, uint16_t blockwidthMost, uint32_t tag )
+{
+ CV3_MostSocketCreate *a = new CV3_MostSocketCreate(this, nodeAddress, epType,
+ epDir, connectionLabel, blockwidthMost, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ConnectSocketsV3( uint16_t nodeAddress, EPDataType_t epType, uint16_t inHandle,
+ uint16_t outHandle, uint16_t offset, uint32_t tag )
+{
+ CV3_ConnectSockets *a = new CV3_ConnectSockets(this, nodeAddress, epType,
+ inHandle, outHandle, offset, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ResourceDestroyV3( uint16_t nodeAddress, uint8_t amountOfHandles, const uint16_t *pHandle,
+ uint32_t tag )
+{
+ CV3_ResourceDestroy *a = new CV3_ResourceDestroy(this, nodeAddress,
+ amountOfHandles, pHandle, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::ConfigureStreamPortV3( uint16_t nodeAddress, uint8_t portInstance, V3I2SPortOption_t option,
+ V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag )
+{
+ CV3_StreamPortConfig *a = new CV3_StreamPortConfig(this, nodeAddress,
+ portInstance, option, mode, delay, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateStreamPortV3( uint16_t nodeAddress, uint8_t portInstance, V3I2SPortSpeed_t clock,
+ V3I2SAlignment_t align, uint32_t tag )
+{
+ CV3_StreamPortCreate *a = new CV3_StreamPortCreate(this, nodeAddress,
+ portInstance, clock, align, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateStreamSocketV3( uint16_t nodeAddress, uint8_t portInstance, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V3I2SPin_t pin, uint32_t tag )
+{
+ CV3_StreamSocketCreate *a = new CV3_StreamSocketCreate(this, nodeAddress,
+ portInstance, epDir, blockWidthI2S, pin, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::CreateSplittedStreamSocketV3( uint16_t nodeAddress, uint8_t portInstance, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V3I2SPin_t pin, uint16_t bytesPerPacket, uint32_t tag )
+{
+ CV3_SplittedStreamSocketCreate *a = new CV3_SplittedStreamSocketCreate(this, nodeAddress,
+ portInstance, epDir, blockWidthI2S, pin, bytesPerPacket, tag);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+void CNetworkDevice::GetRingBreakResultV3( uint16_t nodeAddress, uint32_t tag )
+{
+ CV3_GetRbdResult *a = new CV3_GetRbdResult(nodeAddress);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+bool CNetworkDevice::OpenMostControlChannel( void )
+{
+ bool success = false;
+ for (uint8_t i = 0; !success && i < 10; i++)
+ {
+ if (-1 == controlEndpointRxHandle)
+ controlEndpointRxHandle = open( deviceNameControlRx, O_RDONLY );
+ if (-1 == controlEndpointTxHandle)
+ controlEndpointTxHandle = open( deviceNameControlTx, O_WRONLY );
+ success = (-1 != controlEndpointRxHandle && -1 != controlEndpointTxHandle);
+ if (!success)
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Opened file handles failed TX:%d RX:%d, retrying.."RESETCOLOR"\n", controlEndpointTxHandle, controlEndpointRxHandle);
+ usleep(1000000);
+ }
+ }
+
+ if( success )
+ {
+ iStack = new CIndustrialStack(deviceApi, controlEndpointRxHandle, controlEndpointTxHandle);
+ v1Events = new CV1_OnMostRx(this);
+ v3Events = new CV3_OnMostRx(this);
+ iStack->AddInternalEventListener(this);
+ iStack->AddInternalEventListener(v1Events);
+ iStack->AddInternalEventListener(v3Events);
+ }
+ else
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Failure while opening MOST control channel" \
+ " ('%s' or '%s'), error='%s'"RESETCOLOR"\n"
+ , deviceNameControlRx, deviceNameControlTx, GetErrnoString() );
+ }
+ return success;
+}
+
+void CNetworkDevice::Run( void )
+{
+ iStack->ServiceStack(GetTickCount());
+ usleep( 1000 );
+}
+
+void CNetworkDevice::CloseMostControlChannel( void )
+{
+ close( controlEndpointTxHandle );
+ close( controlEndpointRxHandle );
+ if (NULL != iStack)
+ {
+ delete iStack;
+ iStack = NULL;
+ }
+}
+
+void CNetworkDevice::WaitForIpcResponse( const char *responseMessage )
+{
+ if( isRunning )
+ {
+ strncpy( ( char * )responseToWaitFor, responseMessage, sizeof( responseToWaitFor ) );
+ sem_wait( &methodMutex );
+ responseToWaitFor[0] = '\0';
+ }
+}
+
+bool CNetworkDevice::ConfigureUsbEndpoint( AimType_t aimType, uint8_t endpointAddress, EPDataType_t epType,
+ EPDirection_t epDir, char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize,
+ uint32_t subbufferSize, uint32_t packetsPerTransaction )
+{
+ char systemName[64];
+ char linkName[64];
+ bool success = GetUsbDeviceNames( deviceIndex, endpointAddress, deviceName, deviceNameBufLen,
+ systemName, sizeof( systemName ), linkName, sizeof( linkName ) );
+ if( !success )
+ return success;
+ CloseMostChannel( systemName );
+ switch( epType )
+ {
+ case EP_Synchron:
+ success = ConfigureSyncChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ break;
+ case EP_Isochron:
+ success = ConfigureIsocChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ break;
+ default:
+ break;
+ }
+ if( success )
+ {
+ switch( aimType )
+ {
+ case AIM_AUDIO:
+ success = LinkToAudioDevice( linkName, subbufferSize );
+ break;
+ case AIM_V4L:
+ success = LinkToVideoForLinuxDevice( linkName );
+ break;
+ case AIM_CDEV:
+ default:
+ success = LinkToCharacterDevice( linkName, deviceName );
+ break;
+ }
+ }
+ return success;
+}
+
+bool CNetworkDevice::ConfigureUsbEndpoint( uint8_t endpointAddress, EPDataType_t epType, EPDirection_t epDir,
+ char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize )
+{
+ return ConfigureUsbEndpoint( AIM_CDEV, endpointAddress, epType, epDir, deviceName, deviceNameBufLen,
+ amountOfBuffers, bufferSize, 0, 0 );
+}
+
+bool CNetworkDevice::ConfigureMlbChannel( AimType_t aimType, uint8_t mlbChannelAddress, EPDataType_t epType,
+ EPDirection_t epDir, char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize,
+ uint32_t subbufferSize, uint32_t packetsPerTransaction )
+{
+ char systemName[64];
+ char linkName[64];
+ bool success = GetMlbDeviceNames( deviceIndex, mlbChannelAddress, deviceName, deviceNameBufLen,
+ systemName, sizeof( systemName ), linkName, sizeof( linkName ) );
+ if( !success )
+ return false;
+ CloseMostChannel( systemName );
+ switch( epType )
+ {
+ case EP_Synchron:
+ success = ConfigureSyncChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ if( success )
+ {
+ switch( aimType )
+ {
+ case AIM_AUDIO:
+ success = LinkToAudioDevice( linkName, subbufferSize );
+ break;
+ case AIM_CDEV:
+ default:
+ success = LinkToCharacterDevice( linkName, deviceName );
+ break;
+ }
+ }
+ break;
+ case EP_Isochron:
+ success = ConfigureIsocChannel( systemName, subbufferSize, packetsPerTransaction );
+ if( success )
+ success = ConfigureMostChannel( systemName, epType, epDir, amountOfBuffers, bufferSize );
+ if( success )
+ success = LinkToCharacterDevice( linkName, deviceName );
+ break;
+ default:
+ break;
+ }
+ return success;
+}
+
+bool CNetworkDevice::ConfigureMlbChannel( uint8_t mlbChannelAddress, EPDataType_t epType, EPDirection_t epDir,
+ char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize )
+{
+ return ConfigureMlbChannel( AIM_CDEV, mlbChannelAddress, epType, epDir, deviceName, deviceNameBufLen,
+ amountOfBuffers, bufferSize, 0, 0 );
+}
+
+bool CNetworkDevice::SendMostControlMessage( uint8_t devInst, uint32_t targetAddr, uint32_t nFBlock, uint32_t nInst,
+ uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload )
+{
+ CGeneric_SendMostMessage *a = new CGeneric_SendMostMessage(Payload,
+ nPayloadLen, targetAddr, nFBlock, nInst, nFunc, nOpType, 0xFF);
+ iStack->EnqueueElement(targetAddr, a);
+ a->RemoveReference();
+ return true;
+}
+
+void CNetworkDevice::GetDeviceVersion( uint16_t nodeAddress )
+{
+ CV3_DeviceVersion *a = new CV3_DeviceVersion(this, nodeAddress, 0);
+ iStack->EnqueueElement(nodeAddress, a);
+ a->RemoveReference();
+}
+
+ISReturn_t CNetworkDevice::OnMostMessage(CIndustrialStack *iStack, CISMostMsg *r)
+{
+ if (NULL == r)
+ return ISReturn_NoChange;
+ for (uint32_t i = 0; i < allListeners.Size(); i++)
+ {
+ allListeners[i]->OnMostControlMessage(this, r->SourceAddress, r->TargetAddress,
+ r->FBlock, r->Inst, r->Func, r->OpType, r->PayloadLen, r->Payload);
+ }
+ return ISReturn_NoChange;
+}
+
diff --git a/Src/Network/NetworkDevice.h b/Src/Network/NetworkDevice.h
new file mode 100644
index 0000000..8a67556
--- /dev/null
+++ b/Src/Network/NetworkDevice.h
@@ -0,0 +1,862 @@
+/*
+ * 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 CNetworkDevice class.
+ */
+/*----------------------------------------------------------*/
+#ifndef _NETWORKDEVICE_H_
+#define _NETWORKDEVICE_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+#include "SafeVector.h"
+#include "ScriptXml.h"
+#include "Types.h"
+#include "Thread.h"
+#include "NetworkDeviceListener.h"
+#include "IndustrialStack.h"
+#include "IndustrialStack_Types.h"
+
+typedef enum
+{
+ NetworkState_Unknown,
+ NetworkState_Unavailable,
+ NetworkState_Available,
+ NetworkState_ShutdownInProgress
+} NetworkState_t;
+
+/*----------------------------------------------------------*/
+/*! \brief This class represents an INIC instance.
+ * It will be multiple instanced, for each connected OS81118.
+ * It generates INIC requests and parses INIC responses.
+ */
+/*----------------------------------------------------------*/
+class CNetworkDevice : public CThread, public CSInternalEvent
+{
+private:
+ CIndustrialStack *iStack;
+ CV1_OnMostRx *v1Events;
+ CV3_OnMostRx *v3Events;
+ bool promiscuous;
+ NetworkState_t netState;
+ void *pInic;
+ void *pScriptMemoryArea;
+ bool isRunning;
+ bool isActionPending;
+ uint8_t deviceIndex;
+ uint8_t deviceApi;
+ bool isTimingMaster;
+ uint32_t asyncBandwidth;
+ sem_t methodMutex;
+ int controlEndpointRxHandle;
+ int controlEndpointTxHandle;
+ char *responseToWaitFor[64];
+ char deviceNameControlRx[64];
+ char deviceNameControlTx[64];
+ CSafeVector<CNetworkDeviceListener *> allListeners;
+
+ uint16_t startV3autoForced;
+ uint16_t startV3packetBW;
+
+ bool OpenDevice( const char *systemNameControlRx, const char *systemNameControlTx, const char *linkNameControlRx,
+ const char *linkNameControlTx );
+ bool OpenMostControlChannel( void );
+ void CloseMostControlChannel( void );
+ void WaitForIpcResponse( const char *responseMessage );
+ void ExecuteMcmScript( uint16_t nodeAddress, CSciptXml *scriptXml );
+public:
+ /*----------------------------------------------------------*/
+ /*! \brief Constructor of CNetworkDevice.
+ * \param deviceIndex - The index of the physical device instance of the server device.
+ * Starting at 0 for the first device instance.
+ * \param deviceApi - 1: OS81092, OS81110; 2: OS81118-C-Rev; 3:OS81118-D-Rev
+ * \param isTimingMaster - true, if this device shall act as timing master, otherwise it is timing slave
+ * \param asyncBandwidth - if set as timing master, how many bytes shall be reserved for the asynchronous channel
+ * \param promiscuousMode - true, promiscuous mode. false, perfect match filter with multicast and broadcast enabled. If enabled, tools like Wireshark will capture every packet.
+ */
+ /*----------------------------------------------------------*/
+ CNetworkDevice( uint8_t deviceIndex, uint8_t deviceApi, bool isTimingMaster, uint32_t asyncBandwidth,
+ bool promiscuousMode );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Destructor of CNetworkDevice.
+ */
+ /*----------------------------------------------------------*/
+ virtual ~CNetworkDevice();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Function of background thread.
+ * \note Do never call this method. It is used by internal threads.
+ */
+ /*----------------------------------------------------------*/
+ void Run();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Opens the USB connection to the INIC.
+ * \param controlRxEndpointAddress - The USB endpoint address of the RX direction.
+ * \param controlTxEndpointAddress - The USB endpoint address of the TX direction.
+ * \return true, if successful. false, otherwise.
+ */
+ /*----------------------------------------------------------*/
+ bool OpenUsb( uint8_t controlRxEndpointAddress, uint8_t controlTxEndpointAddress );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Opens the MLB connection to the INIC.
+ * \param controlRxChannelAddress - The MLB channel address of the RX direction.
+ * \param controlTxChannelAddress - The MLB channel address of the TX direction.
+ * \return true, if successful. false, otherwise.
+ */
+ /*----------------------------------------------------------*/
+ bool OpenMlb( uint8_t controlRxChannelAddress, uint8_t controlTxChannelAddress );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Opens the I2C connection to the INIC.
+ * \param inicApi - INIC API Version
+ * \return true, if successful. false, otherwise.
+ */
+ /*----------------------------------------------------------*/
+ bool OpenI2C();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Closes the USB connection to the INIC.
+ */
+ /*----------------------------------------------------------*/
+ void Close();
+
+ /*----------------------------------------------------------*/
+ /*! \brief Returns the used API of the INIC.
+ * \return INIC API Version 1: OS81092, OS81110; 2: OS81118-C-Rev; 3:OS81118-D-Rev
+ */
+ /*----------------------------------------------------------*/
+ uint8_t GetDeviceApi();
+
+ NetworkState_t GetNetState();
+ void SetNetstate( NetworkState_t newState );
+ void SetTimingMaster(bool tm);
+ bool IsTimingMaster();
+ void SetAsyncBandwidth(uint32_t bw);
+ uint32_t GetAsyncBandwidth();
+
+ /*----------------------------------------------------------*/
+ /*! \brief Determines if there are jobs currently in the working queue.
+ * \note This method will block until the result is queried from the worker process.
+ * \return true, if there are pending actions enqueued.
+ */
+ /*----------------------------------------------------------*/
+ bool ActionsPending();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Remove all pending actions from the working queue.
+ */
+ /*----------------------------------------------------------*/
+ void ClearAllPendingActions();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configure the Linux character device driver to handle an USB connection.
+ * \note This overloaded function is used to configure synchronous channels.
+ * \param aimType - Specifies the type of used Linux Driver Application Interface Module.
+ * \param endpointAddress - The USB endpoint address.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param deviceName - On successful configuration, this method stores the name of the character device into the given buffer.
+ * \param deviceNameBufLen - The length of the given buffer.
+ * \param amountOfBuffers - The amount of buffers used in the driver.
+ * \param bufferSize - The amount of bytes used in a single buffer.
+ * \param subbufferSize - The amount of bytes used for a single subbuffer. For isoc channel this maybe 188 or 196 byte.
+ * \param packetsPerTransaction - The amount of packets per transaction.
+ * \return true, if successful. false, otherwise.
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureUsbEndpoint( AimType_t aimType, uint8_t endpointAddress, EPDataType_t epType, EPDirection_t epDir,
+ char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize,
+ uint32_t subbufferSize, uint32_t packetsPerTransaction );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configure the Linux character device driver to handle an USB connection.
+ * \param endpointAddress - The USB endpoint address.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param deviceName - On successful configuration, this method stores the name of the character device into the given buffer.
+ * \param deviceNameBufLen - The length of the given buffer.
+ * \param amountOfBuffers - The amount of buffers used in the driver.
+ * \param bufferSize - The amount of bytes used in a single buffer.
+ * \return true, if successful. false, otherwise.
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureUsbEndpoint( uint8_t endpointAddress, EPDataType_t epType, EPDirection_t epDir, char *deviceName,
+ uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configure the Linux character device driver to handle an MLB connection.
+ * \note This overloaded function is used to configure synchronous channels.
+ * \param aimType - Specifies the type of used Linux Driver Application Interface Module.
+ * \param mlbChannelAddress - The MLB channel address
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param deviceName - On successful configuration, this method stores the name of the character device into the given buffer.
+ * \param deviceNameBufLen - The length of the given buffer.
+ * \param amountOfBuffers - The amount of buffers used in the driver.
+ * \param bufferSize - The amount of bytes used in a single buffer.
+ * \param subbufferSize - The amount of bytes used for a single subbuffer. For isoc channel this maybe 188 or 196 byte.
+ * \param packetsPerTransaction - The amount of packets per transaction.
+ * \return true, if successful. false, otherwise.
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureMlbChannel( AimType_t aimType, uint8_t mlbChannelAddress, EPDataType_t epType, EPDirection_t epDir,
+ char *deviceName, uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize,
+ uint32_t subbufferSize, uint32_t packetsPerTransaction );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configure the Linux character device driver to handle an MLB connection.
+ * \param mlbChannelAddress - The MLB channel address
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param deviceName - On successful configuration, this method stores the name of the character device into the given buffer.
+ * \param deviceNameBufLen - The length of the given buffer.
+ * \param amountOfBuffers - The amount of buffers used in the driver.
+ * \param bufferSize - The amount of bytes used in a single buffer.
+ * \return true, if successful. false, otherwise.
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureMlbChannel( uint8_t mlbChannelAddress, EPDataType_t epType, EPDirection_t epDir, char *deviceName,
+ uint32_t deviceNameBufLen, uint32_t amountOfBuffers, uint32_t bufferSize );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Adds a callback class, which derives CNetworkDeviceListener.
+ * This class will then be informed about any results and changes of MOST transactions.
+ * \note It is possible to register multiple listeners.
+ * \param listener - The class, which wants to be registered for MOST events.
+ */
+ /*----------------------------------------------------------*/
+ void AddListener( CNetworkDeviceListener *listener );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retrieves the amount of registered listeners.
+ * \note Use this method in combination of GetListener()
+ * \return The amount of registered listeners.
+ */
+ /*----------------------------------------------------------*/
+ uint32_t GetAmountOfListners();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets a pointer to the class implementing the CNetworkDeviceListener interface.
+ * \note Use this method in combination of GetAmountOfListners()
+ * \return The pointer to the given instance of Listener.
+ */
+ /*----------------------------------------------------------*/
+ CNetworkDeviceListener *GetListener( uint32_t instance );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets the MOST instance index of the server device.
+ * \return The MOST instance index, starting at 0 for the first instance.
+ */
+ /*----------------------------------------------------------*/
+ uint8_t GetDeviceIndex();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Wait let the scripting engine wait for the given amount of time.
+ * \param timeInMillis - Time value in milliseconds.
+ */
+ /*----------------------------------------------------------*/
+ void ScriptPause( uint32_t timeInMillis );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Execute a bunch of MCM send and receive actions, as descibed in the XML file.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param pPathToScriptXml - Path to the XML file.
+ */
+ /*----------------------------------------------------------*/
+ void ExecuteMcmScript( uint16_t nodeAddress, const char *pPathToScriptXml );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Execute a bunch of MCM send and receive actions, as descibed in the XML zero terminated string.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param pPathToScriptXml - Path to the XML file.
+ */
+ /*----------------------------------------------------------*/
+ void ExecuteMcmScript( uint16_t nodeAddress, const char *pStringBuffer, uint32_t bufferLength );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Sends a NetworkMaster.NOT_OK and NetworkMaster.OK, in order resolve address conflicts.
+ */
+ /*----------------------------------------------------------*/
+ void ToggleNotOk();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retrieves the GroupAddresses of all available MOST devices in this MOST instance.
+ * \note The result of this request is reported in the callback method OnMostDeviceType of the CNetworkDeviceListener class.
+ * Use AddListener to get the result.
+ */
+ /*----------------------------------------------------------*/
+ void GetGroupAddresses( uint8_t maxNodePos );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retrieves the MOST MAC address for the given node address in this MOST instance.
+ * \note The result of this request is reported in the callback method OnMostMacAddress of the CNetworkDeviceListener class.
+ * Use AddListener to get the result.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ */
+ /*----------------------------------------------------------*/
+ void GetMacAddress( uint16_t nodeAddress );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Starts up the MOST on the local INIC of the server device.
+ * \param isTimingMaster - true, if the INIC shall act as a timing master. false, if the device shall act as a timing slave.
+ * \param packetBandWidth - The amount of Bytes, which are reserved for asynchronous data (MEP, MHP).
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void StartMostV1( bool isTimingMaster, uint16_t packetBandWidth );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Performs a network shutdown sequence on the local INIC attached to the server device.
+ * \note This method will cause a chain reaction on the MOST network. All devices will switch of their output signal on MOST.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void MostNetworkShutdownV1();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Enables the usage of the MLB bus for the device on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param mlbSpeed - The used MLB speed.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void OpenMlbV1( uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Sets the MOST MAC address for the device on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param macAddress1 - The 1st byte of the MAC address.
+ * \param macAddress2 - The 2nd byte of the MAC address.
+ * \param macAddress3 - The 3rd byte of the MAC address.
+ * \param macAddress4 - The 4th byte of the MAC address.
+ * \param macAddress5 - The 5th byte of the MAC address.
+ * \param macAddress6 - The 6th byte of the MAC address.
+ * \param persistent - true, if the given MAC address shall be stored persistent into the INIC flash memory.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void SetMostMacAddressV1( uint16_t nodeAddress, uint8_t macAddress1, uint8_t macAddress2, uint8_t macAddress3,
+ uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6, bool persistent );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Enables the usage of the MLB bus for the device on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param tsiPortId - The instance id of the used TSI port.
+ * \param tsiPortMode - The used mode for this TSI port.
+ * \note This is an INIC API Version 1 command. Use it for OS81110 only.
+ */
+ /*----------------------------------------------------------*/
+ void OpenTsiV1( uint16_t nodeAddress, V1TsiPortInstance_t tsiPortId, V1TsiPortMode tsiPortMode );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a TSI socket on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param portInst - The port instance id of the TSI port.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthTsi -The block width in bytes to be allocated on the MLB bus.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void CreateTsiSocketV1( uint16_t nodeAddress, V1TsiPortInstance_t portInst,
+ EPDataType_t epType, EPDirection_t epDir,uint16_t blockWidthTsi, uint32_t tag );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a MLB socket on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param blockWidthMlb -The block width in bytes to be allocated on the MLB bus.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void CreateMlbSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir, uint16_t mlbChannelAddress,
+ uint16_t blockWidthMlb, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a MLB socket on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param blockWidthMlb -The block width in bytes of this singular splitted socked.
+ * \param splittedOffset - Offset in between the splitted socket.
+ * \param blockWidthCombined - The block width in bytes of all splitted sockets combined.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void CreateSplittedMlbSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t mlbChannelAddress, uint16_t blockWidthMlb, uint16_t splittedOffset, uint16_t blockWidthCombined,
+ uint32_t tag );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a MOST socket on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param connectionLabel - Only in case of if epDir is "EPDIR_IN": The connection label, which this socket will be bound.
+ * Otherwise, the value will be ignored.
+ * \param blockwidthMost - The block width in bytes to be allocated on the MOST bus.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void CreateMostSocketV1( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir, uint16_t connectionLabel,
+ uint16_t blockwidthMost, uint32_t tag );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param handle - The handle of socket (will be reported by the callback callback methods of the create socket methods).
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void DestroySocketV1( uint16_t nodeAddress, uint8_t handle, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param handle - The handle of socket (will be reported by the callback callback methods of the connect socket method).
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void DisconnectSocketsV1( uint16_t nodeAddress, uint8_t handle, uint32_t tag );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Connects two different sockets, which then is called a connection, on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param inHandle - The handle of the in-socket (will be reported by the callback callback methods of the create socket methods).
+ * \param outHandle - * The handle of out-socket (will be reported by the callback callback methods of the create socket methods).
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 1 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void ConnectSocketsV1( uint16_t nodeAddress, uint8_t inHandle, uint8_t outHandle, uint32_t tag );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures an I2S port on the given node address.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void OpenStreamPortV1( uint16_t nodeAddress, V1I2SPortClkDriveMode_t portMode,
+ V1I2SStreamingPortMode_t streamPortMode, V1I2SStreamingDataFormat_t format, uint32_t tag );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an I2S socket on the given node address.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param epDir - he Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthI2S - The block width in bytes allocated on the I2S bus.
+ * \param pin - The physical I2S data pin of the INIC.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void CreateStreamSocketV1( uint16_t nodeAddress, EPDirection_t epDir, uint16_t blockWidthI2S, V1I2SPin_t pin,
+ uint32_t tag );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an I2S socket on the given node address.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param epDir - he Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthI2S - The block width in bytes allocated on the I2S bus.
+ * \param splittedOffset - Offset in between the splitted socket.
+ * \param blockWidthCombined - The block width in bytes of all splitted sockets combined.
+ * \param pin - The physical I2S data pin of the INIC.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ void CreateSplittedStreamSocketV1( uint16_t nodeAddress, EPDirection_t epDir, uint16_t blockWidthI2S,
+ uint16_t splittedOffset, uint16_t blockWidthCombined, V1I2SPin_t pin, uint32_t tag );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Attach to a local INIC on the server device.
+ * \note This command has to be called before any other commands to the local INIC.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void AttachV3();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Destroyes any resource on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param sync - true, if the device shall be used afterwise. false, if the device is going to suspend (shutdown).
+ * \note In any case (regardless if sync is true or false), all ports, sockets and connects are going to be destroyed).
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void DeviceSyncV3( uint16_t nodeAddress, bool sync );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Performs a network startup sequence on the local INIC attached to the server device.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118-D Revision
+ */
+ /*----------------------------------------------------------*/
+ void MostNetworkStartupV3( uint16_t autoForcedNotAvailable, uint16_t packetBW );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Performs a network startup sequence on the local INIC attached to the server device, after MostNetworkStartupV3 with parameters had failed.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118-D Revision
+ * \note Call this method only if the MostNetworkStartupV3( uint16_t autoForcedNotAvailable, uint16_t packetBW ) had failed. This will be treated as retry.
+ */
+ /*----------------------------------------------------------*/
+ void MostNetworkStartupV3();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Performs a network shutdown sequence on the local INIC attached to the server device.
+ * \note This method will cause a chain reaction on the MOST network. All devices will switch of their output signal on MOST.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void MostNetworkShutdownV3();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Closes the IPC connection to local attached INIC.
+ * \note This will also cleanup any used resource in the INIC.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void InicUnsychronizeV3();
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Sets the MOST MAC address for the device on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param macAddress1 - The 1st byte of the MAC address.
+ * \param macAddress2 - The 2nd byte of the MAC address.
+ * \param macAddress3 - The 3rd byte of the MAC address.
+ * \param macAddress4 - The 4th byte of the MAC address.
+ * \param macAddress5 - The 5th byte of the MAC address.
+ * \param macAddress6 - The 6th byte of the MAC address.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118-D Rev
+ */
+ /*----------------------------------------------------------*/
+ void SetMostMacAddressV3( uint16_t nodeAddress, uint8_t macAddress1, uint8_t macAddress2, uint8_t macAddress3,
+ uint8_t macAddress4, uint8_t macAddress5, uint8_t macAddress6 );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Enables the usage of the MLB bus for the device on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param mlbSpeed - The speed of the MLB bus.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void OpenMlbV3( uint16_t nodeAddress, MlbPortSpeed_t mlbSpeed );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an USB socket on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param endPointAddress - The USB endpoint address.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \param packetsPerFrame - The amount of packets stored in a single USB frame (512 byte).
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateUsbSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir, uint8_t endPointAddress,
+ uint16_t packetsPerFrame, uint32_t tag );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an splitted USB socket on the given node address to use with Combiner or Splitter.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param endPointAddress - The USB endpoint address.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \param packetsPerFrame - The amount of packets stored in a single USB frame (512 byte).
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateSplittedUsbSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir,
+ uint8_t endPointAddress, uint16_t packetsPerFrame, uint16_t bytesPerPacket, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a MLB socket on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param blockwidthMlb - The block width in bytes to be allocated on the MLB bus.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateMlbSocketV3( uint16_t nodeAddress, uint16_t mlbPortHandle, EPDataType_t epType, EPDirection_t epDir,
+ uint16_t mlbChannelAddress, uint16_t blockwidthMlb, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a splitted MLB socket on the given node address to use with Combiner or Splitter.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param blockwidthMlb - The block width in bytes to be allocated on the MLB bus.
+ * \param bytesPerPacket - The total number of data bytes to be transfered each MOST frame.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateSplittedMlbSocketV3( uint16_t nodeAddress, uint16_t mlbPortHandle, EPDataType_t epType,
+ EPDirection_t epDir, uint16_t mlbChannelAddress, uint16_t blockwidthMlb, uint16_t bytesPerPacket,
+ uint32_t tag );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a MOST socket on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this MOST channel.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param connectionLabel - Only in case of if epDir is "EPDIR_IN": The connection label, which this socket will be bound.
+ * Otherwise, the value will be ignored.
+ * \param blockwidthMost - The block width in bytes to be allocated on the MOST bus.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateMostSocketV3( uint16_t nodeAddress, EPDataType_t epType, EPDirection_t epDir, uint16_t connectionLabel,
+ uint16_t blockwidthMost, uint32_t tag );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Connects two different sockets, which then is called a connection, on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param epType - The data type, which then will be transmitted on this connection.
+ * \param inHandle - The handle of the in-socket (will be reported by the callback callback methods of the create socket methods).
+ * \param outHandle - * The handle of out-socket (will be reported by the callback callback methods of the create socket methods).
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void ConnectSocketsV3( uint16_t nodeAddress, EPDataType_t epType, uint16_t inHandle, uint16_t outHandle,
+ uint16_t offset, uint32_t tag );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Destroyes up to three resources (Ports or connections) on the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \param amountOfHandles - The amount of resources to be destroyed. (value must be between 1 to 3).
+ * \param handle1 - The first resource to be destroyed.
+ * \param handle2 - The second resource to be destroyed.
+ * \param handle3 - The third resource to be destroyed.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void ResourceDestroyV3( uint16_t nodeAddress, uint8_t amountOfHandles, const uint16_t *pHandle, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures an I2S port on the given node address.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param option - The I2S port option.
+ * \param mode - The I2S clock mode.
+ * \param delay - The I2S delay mode.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void ConfigureStreamPortV3( uint16_t nodeAddress, uint8_t portInstance, V3I2SPortOption_t option,
+ V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an I2S port on the given node address.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param clock - The I2S port speed in multiple of MOST base clock.
+ * \param align - The I2S data format alignment.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateStreamPortV3( uint16_t nodeAddress, uint8_t portInstance, V3I2SPortSpeed_t clock,
+ V3I2SAlignment_t align, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an I2S socket on the given node address.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param epDir - he Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthI2S - The block width in bytes allocated on the I2S bus.
+ * \param pin - The physical I2S data pin of the INIC.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateStreamSocketV3( uint16_t nodeAddress, uint8_t portInstance, EPDirection_t epDir, uint16_t blockWidthI2S,
+ V3I2SPin_t pin, uint32_t tag );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an splitted I2S socket on the given node address to use with Combiner or Splitter.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param epDir - he Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthI2S - The block width in bytes allocated on the I2S bus.
+ * \param pin - The physical I2S data pin of the INIC.
+ * \param bytesPerPacket - The total number of data bytes to be transfered each MOST frame.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void CreateSplittedStreamSocketV3( uint16_t nodeAddress, uint8_t portInstance, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V3I2SPin_t pin, uint16_t bytesPerPacket, uint32_t tag );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates an I2S socket on the given node address.
+ * \param nodeAddr -The device with this MOST node address raised this event.
+ * \param tag - Any 32 bit value. This value will be unmodified passed back in the corresponding callback method.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void GetRingBreakResultV3( uint16_t nodeAddress, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Sends the given Control Message out to MOST ring.
+ * \param targetAddr - The MOST target address
+ * \param nFBlock - The MOST Function Block Identifier
+ * \param nInst - The MOST Function Block Instance Identifier
+ * \param nFunc - The MOST Function Block Function Identifier
+ * \param nPayloadLen - The amount of bytes stored in Payload
+ * \param Payload - The pointer to the payload byte array.
+ */
+ /*----------------------------------------------------------*/
+ bool SendMostControlMessage( uint8_t devInst, uint32_t targetAddr, uint32_t nFBlock, uint32_t nInst,
+ uint32_t nFunc, uint8_t nOpType, uint32_t nPayloadLen, const uint8_t *Payload );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets the device information for the given node address.
+ * \param nodeAddress - The MOST node address (e.g. 0x101).
+ * \note The corresponding callback to this request is OnDeviceVersion.
+ * \note This is an INIC API Version 3 command. Use it for e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ void GetDeviceVersion( uint16_t nodeAddress );
+
+ /* Callback from underlying layers */
+ virtual ISReturn_t OnMostMessage(CIndustrialStack *iStack, CISMostMsg *r);
+};
+
+#endif //_NETWORKDEVICE_H_
diff --git a/Src/Network/NetworkDeviceListener.cpp b/Src/Network/NetworkDeviceListener.cpp
new file mode 100644
index 0000000..be62d33
--- /dev/null
+++ b/Src/Network/NetworkDeviceListener.cpp
@@ -0,0 +1,306 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <Board.h>
+#include "Console.h"
+#include "NetworkDeviceListener.h"
+
+void CNetworkDeviceListener::OnSync( void *source, bool isSynced )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnSync\n" );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnNetworkState\n" );
+}
+
+void CNetworkDeviceListener::OnNetworkStartupV3( void *source, bool success )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnNetworkStartupV3, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnNetworkShutdownV3( void *source, bool success )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnNetworkShutdownV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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( success )
+ {
+ ConsolePrintf( PRIO_LOW,
+ "BASE->OnMostMacAddress:nodeAddress:0x%X, MAC-Address:%02X-%02X-%02X-%02X-%02X-%02X)\n", nodeAddress,
+ macAddress1, macAddress2, macAddress3, macAddress4, macAddress5, macAddress6 );
+ }
+ else
+ {
+ ConsolePrintf( PRIO_ERROR,
+ RED"BASE->OnMostMacAddress reports failure for nodeAddress:0x%X"RESETCOLOR"\n", nodeAddress );
+ }
+}
+
+void CNetworkDeviceListener::OnMostDeviceType( void *source, bool success, uint16_t nodeAddress, uint16_t deviceType )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnMostDeviceType, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnInitCompleteV1( void *source )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnInitCompleteV1\n" );
+}
+
+void CNetworkDeviceListener::OnNetOnV1( void *source, bool isMaster )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnNetOnV1, mode=%s\n", ( isMaster ? "master" : "slave" ) );
+}
+
+void CNetworkDeviceListener::OnShutDownV1( void *source )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnShutDownV1\n" );
+}
+
+void CNetworkDeviceListener::OnNprV1( void *source, uint8_t npr )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnNprV1, NPR=%d\n", npr );
+}
+
+void CNetworkDeviceListener::OnUnlockV1( void *source )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnUnlockV1\n" );
+}
+
+void CNetworkDeviceListener::OnMprV1( void *source, uint8_t oldMpr, uint8_t newMpr )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnMprV1, old MPR=%d, new MPR:%d\n", oldMpr, newMpr );
+}
+
+void CNetworkDeviceListener::OnOpenTsiV1( void *source, bool success, uint16_t nodeAddress )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnOpenTsiV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateTsiSocketV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnOpenMlbV1( void *source, bool success, uint16_t nodeAddress )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnOpenMlbV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateMlbSocketV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateMostSocketV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnConnectSocketsV1( void *source, bool success, uint16_t nodeAddr,
+ uint16_t inSocketHandle, uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnConnectSocketsV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnDestroySocketV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle,
+ uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnDestroySocketV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnDisconnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle,
+ uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnDisconnectSocketsV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnOpenI2SPortV1( void *source, bool success, uint16_t nodeAddress,
+ V1I2SPortClkDriveMode_t portMode, V1I2SStreamingDataFormat_t format, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnOpenI2SPortV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnCreateI2SSocketV1( void *source, bool success, uint16_t nodeAddr, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V1I2SPin_t pin, uint16_t socketHandle, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateI2SSocketV1, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnOpenMlbV3( void *source, bool success, uint16_t nodeAddress, uint16_t mlbPortHandle )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnOpenMlbV2, success=%s, Handle:%X\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ), mlbPortHandle );
+}
+
+void CNetworkDeviceListener::OnCreateUsbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
+ EPDirection_t epDir, uint8_t endPointAddress, uint16_t socketHandle, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateUsbSocketV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateSplittedUsbSocketV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateMlbSocketV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 splittertHandle, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateSplittedMlbSocketV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateMostSocketV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnConnectSocketsV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
+ uint16_t inSocketHandle, uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnConnectSocketsV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+
+void CNetworkDeviceListener::OnResourceDestroyV3( void *source, bool success, uint16_t nodeAddress,
+ uint8_t amountOfHandles, const uint16_t *pHandle, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnResourceDestroyV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnConfigureI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
+ V3I2SPortOption_t option, V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnConfigureI2SPortV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnCreateI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
+ V3I2SPortSpeed_t clock, V3I2SAlignment_t align, uint32_t tag )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateI2SPortV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateI2SSocketV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->CNetworkDeviceListener::OnCreateSplittedI2SSocketV2, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
+
+void CNetworkDeviceListener::OnRbdResultV3( void *source, uint16_t nodeAddress, uint8_t result, uint8_t position,
+ uint8_t status, uint16_t id )
+{
+ ConsolePrintfStart( PRIO_HIGH, YELLOW"BASE->OnRbdResultV3: Diagnosis Result from node=0x%X, result=0x%X (",
+ nodeAddress, result );
+ switch( result )
+ {
+ case 0:
+ ConsolePrintfContinue( "NoError" );
+ break;
+ case 1:
+ ConsolePrintfContinue( "PosDetected" );
+ break;
+ case 2:
+ ConsolePrintfContinue( "DiagFailed" );
+ break;
+ case 3:
+ ConsolePrintfContinue( "Pos0WeakSig" );
+ break;
+ case 0xFF:
+ ConsolePrintfContinue( "No result" );
+ break;
+ default:
+ ConsolePrintfContinue( "UNKNOWN" );
+ break;
+ }
+ ConsolePrintfExit( ") Position: %d"RESETCOLOR"\n", position );
+}
+
+void CNetworkDeviceListener::OnControlChannelReadEnd( void *source )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->OnControlChannelReadEnd\n" );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "Base->OnMostControlMessage\n" );
+}
+
+void CNetworkDeviceListener::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 )
+{
+ ConsolePrintf( PRIO_LOW, "BASE->OnDeviceVersion::OnDeviceVersion, success=%s\n",
+ ( success ? GREEN"yes"RESETCOLOR : RED"no"RESETCOLOR ) );
+}
diff --git a/Src/Network/NetworkDeviceListener.h b/Src/Network/NetworkDeviceListener.h
new file mode 100644
index 0000000..719bc5f
--- /dev/null
+++ b/Src/Network/NetworkDeviceListener.h
@@ -0,0 +1,568 @@
+/*
+ * 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 CNetworkDeviceListener class.
+ */
+/*----------------------------------------------------------*/
+#ifndef _NETWORKDEVICELISTENER_H_
+#define _NETWORKDEVICELISTENER_H_
+
+#include <stdint.h>
+#include "Types.h"
+
+/*----------------------------------------------------------*/
+/*! \brief This class defines callbacks methods which will be called by CNetworkDevice to any
+ * registered listener. Also this class implements empty implementation of each method.
+ * So the integrator has only to override methods, he is interessted in.
+ */
+/*----------------------------------------------------------*/
+class CNetworkDeviceListener
+{
+public:
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a sync event has been detected on the server network device.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnSync( void *source, bool isSynced );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a Network State event has been detected on the server network device.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param mpValChanged - true, there was a change in the Maximum Position Information. false, no change.
+ * \param systemNotOk - true, system state changes to NotOk. false, no change.
+ * \param mostAvailable - true, the MOST network is available. false, The MOST network is not available for sending control/packet data.
+ * \param availableSubState - 0=Regular, 2=Diagnosis, 4=RxOnBlocked, 6=ForcedNA, 0x10=Unstable, 0x11=Stable
+ * \param availableTransition - 0=Command, 1=RxActivity, 2=DiagnosisReady, 0x10=Normal, 0x11=SuddenSignalOff, 0x12=CriticalUnlock
+ * 0x13=ErrorSystem, 0xFF=NoTransition
+ * \param nodeAddress - The assigned MOST node address.
+ * \param nodePos - The position in the MOST ring.
+ * \param maxPos - The maximum amount of devices in the MOST ring.
+ * \param packetBW - The amount of bytes reserved for packet channel (MEP/MHP)
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+
+ virtual void OnInitCompleteV1( void *source );
+ virtual void OnUnlockV1( void *source );
+ virtual void OnNetOnV1( void *source, bool isMaster );
+ virtual void OnShutDownV1( void *source );
+ virtual void OnNprV1( void *source, uint8_t npr );
+ virtual void OnMprV1( void *source, uint8_t oldMpr, uint8_t newMpr );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever the MOST had been tried to start.
+ * \param success - true, when the operation was successful.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118 D-Rev
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnNetworkStartupV3( void *source, bool success );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever the MOST had been tried to shutdown.
+ * \param success - true, when the operation was successful.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118 D-Rev
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnNetworkShutdownV3( void *source, bool success );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MAC address has been changed in the network.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddress - The device with this MOST node address raised this event.
+ * \param macAddress1 - The 1st byte of the MAC address.
+ * \param macAddress2 - The 2nd byte of the MAC address.
+ * \param macAddress3 - The 3rd byte of the MAC address.
+ * \param macAddress4 - The 4th byte of the MAC address.
+ * \param macAddress5 - The 5th byte of the MAC address.
+ * \param macAddress6 - The 6th byte of the MAC address.
+ * \note This is event will be raised by all INIC APIS (V1 & V2).
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a Device type has been detected.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param nodeAddress - The device with this MOST node address raised this event.
+ * \param deviceType - Identifier which sorts the MOST device to a specific function group.
+ * \note In this implementation the Device Type is simply derived from the Group Address set in the INIC config string!
+ * \note This is event will be raised by all INIC APIS (V1 & V2).
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnMostDeviceType( void *source, bool success, uint16_t nodeAddress, uint16_t deviceType );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever the TSI bus was opened.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddress - The device with this MOST node address raised this event.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnOpenTsiV1( void *source, bool success, uint16_t nodeAddress );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a TSI socket was created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param tsiPortInst - The use TSI port.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthMlb - The block width in bytes allocated on the MLB bus.
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or closing this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever the MLB bus was opened.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddress - The device with this MOST node address raised this event.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnOpenMlbV1( void *source, bool success, uint16_t nodeAddress );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MLB socket was created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthMlb - The block width in bytes allocated on the MLB bus.
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or closing this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MOST socket was created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockwidthMost - The block width in bytes allocated on the MOST bus.
+ * \param connectionLabel - The MOST connection label, which this socket will be bound.
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or closing this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever two MOST sockets where connected.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param inSocketHandle - The user given IN-handle.
+ * \param outSocketHandle - The user given OUT-handle.
+ * \param connectionHandle - Unique handle for this connection. Use this for disconnecting this connection again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnConnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t inSocketHandle,
+ uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MOST socket was deestroyed.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddress - The device with this MOST node address raised this event.
+ * \param handle - The unique handle for this socket. After this call, the handle is invalid.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnDestroySocketV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MOST connection was disconnected.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddress - The device with this MOST node address raised this event.
+ * \param handle - The unique handle for this connection. After this call, the handle is invalid.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 1 event. It is raised from e.g. OS81110
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnDisconnectSocketsV1( void *source, bool success, uint16_t nodeAddr, uint16_t handle, uint32_t tag );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a I2S port has been configured.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnOpenI2SPortV1( void *source, bool success, uint16_t nodeAddress, V1I2SPortClkDriveMode_t portMode,
+ V1I2SStreamingDataFormat_t format, uint32_t tag );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a I2S socket has been created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param epDir - he Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthI2S - The block width in bytes allocated on the I2S bus.
+ * \param pin - The physical I2S data pin of the INIC.
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or destroying this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnCreateI2SSocketV1( void *source, bool success, uint16_t nodeAddr, EPDirection_t epDir,
+ uint16_t blockWidthI2S, V1I2SPin_t pin, uint16_t socketHandle, uint32_t tag );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever the MLB bus was opened.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddress - The device with this MOST node address raised this event.
+ * \param mlbPortHandle - The device with this MOST node address raised this event.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnOpenMlbV3( void *source, bool success, uint16_t nodeAddress, uint16_t mlbPortHandle );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a USB socket was created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param endPointAddress - The USB endpoint address, which is now usable.
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or closing this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnCreateUsbSocketV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
+ EPDirection_t epDir, uint8_t endPointAddress, uint16_t socketHandle, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a USB socket was created, which uses a Splitter or a Combiner.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param endPointAddress - The USB endpoint address, which is now usable.
+ * \param usbHandle - Unique handle for this USB socket. Do not use this for creating connections!
+ * \param splitterHandle - Unique handle for this Splitter socket. Use this for creating connections or closing this socket again!
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MLB socket was created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthMlb - The block width in bytes allocated on the MLB bus.
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or closing this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MLB socket was created, which uses a Splitter or a Combiner.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthMlb - The block width in bytes allocated on the MLB bus.
+ * \param mlbChannelAddress - The MLB channel address (even value).
+ * \param mlbSocketHandle - Unique handle for this socket. Use this for creating connections or closing this socket again.
+ * \param splitterHandle - Unique handle for this Splitter socket. Use this for creating connections or closing this socket again!
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a MOST socket was created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this endpoint.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockwidthMost - The block width in bytes allocated on the MOST bus.
+ * \param connectionLabel - The MOST connection label, which this socket will be bound.
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or destroying this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever two MOST sockets where connected.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param epType - The data type, which then will be transmitted on this connection.
+ * \param inSocketHandle - The user given IN-handle.
+ * \param outSocketHandle - The user given OUT-handle.
+ * \param connectionHandle - Unique handle for this connection. Use this for destroying this connection again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnConnectSocketsV3( void *source, bool success, uint16_t nodeAddr, EPDataType_t epType,
+ uint16_t inSocketHandle, uint16_t outSocketHandle, uint16_t connectionHandle, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever MOST resources where destroyed.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param amountOfHandles - The amount of resources to be destroyed. (value will be between 1 to 3).
+ * \param pHandle - Pointer to the resource list
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnResourceDestroyV3( void *source, bool success, uint16_t nodeAddr, uint8_t amountOfHandles,
+ const uint16_t *pHandle, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a I2S port has been configured.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param option - The I2S port option.
+ * \param mode - The I2S clock mode.
+ * \param delay - The I2S delay mode.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnConfigureI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
+ V3I2SPortOption_t option, V3I2SClockMode_t mode, V3I2SDelayMode_t delay, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a I2S port has been created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param clock - The I2S port speed in multiple of MOST base clock.
+ * \param align - The I2S data format alignment.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnCreateI2SPortV3( void *source, bool success, uint16_t nodeAddr, uint8_t portInstance,
+ V3I2SPortSpeed_t clock, V3I2SAlignment_t align, uint32_t tag );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a I2S socket has been created.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param epDir - he Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthI2S - The block width in bytes allocated on the I2S bus.
+ * \param pin - The physical I2S data pin of the INIC.
+ * \param socketHandle - Unique handle for this socket. Use this for creating connections or destroying this socket again.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when ever a I2S socket has been created, which uses a Splitter or a Combiner.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \param portInstance - The I2S port instance. 0 = Port A, 1 = Port B.
+ * \param epDir - The Direction of the stream. (EPDIR_IN == Data from the INIC to the EHC, EPDIR_OUT == Data from the EHC to the INIC)
+ * \param blockWidthI2S - The block width in bytes allocated on the I2S bus.
+ * \param pin - The physical I2S data pin of the INIC.
+ * \param i2sSocketHandle - Unique handle for this socket. Use this for creating connections or destroying this socket again.
+ * \param splitterHandle - Unique handle for this Splitter socket. Use this for creating connections or closing this socket again!
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when a Ring Break Diagnosis Result was received.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param nodeAddr - The device with this MOST node address raised this event.
+ * \praram result - The ring break diagnosis result
+ * \param position - Relative position to the ring break.
+ * \param status - Gives information about the activity state.
+ * \param id - The RBD identifier as configured in config string.
+ * \note This is an INIC API Version 3 event. It is raised from e.g. OS81118
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnRbdResultV3( void *source, uint16_t nodeAddress, uint8_t result, uint8_t position,
+ uint8_t status, uint16_t id );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Callback, when the MOST control channel receive thread has ended.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ */
+ /*----------------------------------------------------------*/
+ virtual void OnControlChannelReadEnd( void *source );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief This callback method is called whenever a MOST control message was sent or received.
+ * \note In order to be informed about this event, derive this class, implement this method and register the class with AddListener method of CNetwork class.
+ * \note The user may interpret the data and sent a corresponding MOST control message via CNetwork::SendMostControlMessage.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param sourceAddr - The MOST source address (may be not accurate)
+ * \param targetAddr - The MOST target address
+ * \param nFBlock - The MOST Function Block Identifier
+ * \param nInst - The MOST Function Block Instance Identifier
+ * \param nFunc - The MOST Function Block Function Identifier
+ * \param nPayloadLen - The amount of bytes stored in Payload
+ * \param Payload - The pointer to the payload byte array.
+ *
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+ /*----------------------------------------------------------*/
+ /*! \brief This callback method is as result of the DeviceVersion query.
+ * \param source - Cast this pointer to (CNetworkDevice*), it points to server network device, which received this event.
+ * \param success - true, when the operation was successful.
+ * \param sourceAddr - The device with this MOST node address raised this event.
+ * \param productId - Unique identifier that represents the product name.
+ * \param fwVersion - INIC firmware version: Byte[3] Major, Byte[2] Minor, Byte[1] Release.
+ * \param buildVersion - Build version of the firmware.
+ * \param hwVersion - Chip revision number.
+ * \param diagnosisId - Unique diagnosis identifier of the device.
+ * \param tag - Any 32 bit value. This value was passed to the corresponding function call of the CNetworkDevice class.
+ */
+ /*----------------------------------------------------------*/
+ virtual void 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 );
+
+};
+
+#endif //_NETWORKDEVICELISTENER_H_
diff --git a/Src/Network/Network_CB.cpp b/Src/Network/Network_CB.cpp
new file mode 100644
index 0000000..3a91cc2
--- /dev/null
+++ b/Src/Network/Network_CB.cpp
@@ -0,0 +1,1823 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#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<CChannelConfiguration *> 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);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Network/Network_Private.cpp b/Src/Network/Network_Private.cpp
new file mode 100644
index 0000000..2aaef6e
--- /dev/null
+++ b/Src/Network/Network_Private.cpp
@@ -0,0 +1,695 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#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()
+#define MAX_MOST_DEVICES 4
+
+void CNetwork::DestroyAllResources( CNetworkDevice *device, uint16_t nodeAddress )
+{
+ if( NULL == device )
+ return;
+
+ CNodeEntry *node = CNodeEntry::GetNodeEntry( device->GetDeviceIndex(), nodeAddress );
+ if( NULL == node )
+ return;
+
+ sem_wait( &vodXmlMutex );
+ uint32_t apiVer = vodXml->GetDeviceApi( node->deviceType );
+ sem_post( &vodXmlMutex );
+ if( 1 == apiVer )
+ {
+ for( int i = 0; i < node->GetAmountOfConnections(); i++ )
+ {
+ CNodeConnectionEntry *connection = node->GetConnectionByIndex( i );
+ if( NULL == connection || NULL == connection->channelConfig )
+ continue;
+
+ uint32_t inHandle = connection->inHandle;
+ uint32_t outHandle = connection->outHandle;
+ uint32_t conHandle = connection->connectHandle;
+ NodeConnectionState_t inState = connection->inSocketState;
+ NodeConnectionState_t outState = connection->outSocketState;
+ NodeConnectionState_t conState = connection->connectedSocketState;
+ uint32_t channelId = connection->channelConfig->channelId;
+ connection->deviceName[0] = '\0';
+ connection->mostConnectionLabel = 0xFFFFFFFF;
+ connection->inHandle = 0xFFFFFFFF;
+ connection->outHandle = 0xFFFFFFFF;
+ connection->connectHandle = 0xFFFFFFFF;
+ connection->inSocketState = NodeConnection_NotUsed;
+ connection->outSocketState = NodeConnection_NotUsed;
+ connection->connectedSocketState = NodeConnection_NotUsed;
+ if( NodeConnection_NotUsed != conState && 0xFFFFFFFF != conHandle )
+ {
+ device->DisconnectSocketsV1( nodeAddress, conHandle, channelId );
+ }
+ if( NodeConnection_NotUsed != inState && 0xFFFFFFFF != inHandle )
+ {
+ device->DestroySocketV1( nodeAddress, inHandle, channelId );
+ }
+ if( NodeConnection_NotUsed != outState && 0xFFFFFFFF != outHandle )
+ {
+ device->DestroySocketV1( nodeAddress, outHandle, channelId );
+ }
+ RaiseUnavailable( connection );
+ }
+ }
+ else if( 2 == apiVer || 3 == apiVer )
+ {
+ uint8_t amount;
+#define MAX_DESTROY_ELEMENTS 10
+ uint16_t handles[MAX_DESTROY_ELEMENTS];
+
+ //Start to destroy the connections first:
+ do
+ {
+ amount = 0;
+ for( int i = 0; amount < MAX_DESTROY_ELEMENTS && i < node->GetAmountOfConnections(); i++ )
+ {
+ CNodeConnectionEntry *connection = node->GetConnectionByIndex( i );
+ if( NULL == connection || NULL == connection->channelConfig )
+ continue;
+ if( NodeConnection_NotUsed != connection->connectedSocketState )
+ {
+ handles[amount++] = connection->connectHandle;
+ connection->connectHandle = 0xFFFFFFFF;
+ connection->connectedSocketState = NodeConnection_NotUsed;
+ }
+ }
+ if( amount != 0 )
+ {
+ device->ResourceDestroyV3( nodeAddress, amount, handles, 0 );
+ }
+ }
+ while( amount != 0 );
+
+ do
+ {
+ amount = 0;
+ //Continue to destroy the In and Out sockets:
+ for( int i = 0; amount < MAX_DESTROY_ELEMENTS && i < node->GetAmountOfConnections(); i++ )
+ {
+ CNodeConnectionEntry *connection = node->GetConnectionByIndex( i );
+ if( NULL == connection || NULL == connection->channelConfig )
+ continue;
+ if( ( NodeConnection_NotUsed != connection->inSocketState )
+ && ( 0xFFFFFFFF != connection->inHandle ) )
+ {
+ handles[amount++] = connection->inHandle;
+ for( int j = 0; j < node->GetAmountOfConnections(); j++ )
+ {
+ if( i == j )
+ continue;
+ CNodeConnectionEntry *otherConn = node->GetConnectionByIndex( j );
+ if( ( otherConn != NULL ) && ( otherConn->inHandle == connection->inHandle ) )
+ {
+ otherConn->inHandle = 0xFFFFFFFF;
+ otherConn->inSocketState = NodeConnection_NotUsed;
+ }
+ }
+ connection->inHandle = 0xFFFFFFFF;
+ connection->inSocketState = NodeConnection_NotUsed;
+ }
+ if( amount < MAX_DESTROY_ELEMENTS &&
+ ( NodeConnection_NotUsed != connection->outSocketState )
+ && ( 0xFFFFFFFF != connection->outHandle ) )
+ {
+ handles[amount++] = connection->outHandle;
+ for( int j = 0; j < node->GetAmountOfConnections(); j++ )
+ {
+ if( i == j )
+ continue;
+ CNodeConnectionEntry *otherConn = node->GetConnectionByIndex( j );
+ if( ( otherConn != NULL ) && ( otherConn->outHandle == connection->outHandle ) )
+ {
+ otherConn->outHandle = 0xFFFFFFFF;
+ otherConn->outSocketState = NodeConnection_NotUsed;
+ }
+ }
+ connection->outHandle = 0xFFFFFFFF;
+ connection->outSocketState = NodeConnection_NotUsed;
+ RaiseUnavailable( connection );
+ }
+
+ }
+ if( amount != 0 )
+ {
+ device->ResourceDestroyV3( nodeAddress, amount, handles, 0 );
+ }
+ }
+ while( amount != 0 );
+
+ //Last step destroy Splitter / Combiner input / output
+ do
+ {
+ amount = 0;
+ for( int i = 0; i < node->GetAmountOfConnections(); i++ )
+ {
+ CNodeConnectionEntry *connection = node->GetConnectionByIndex( i );
+ if( NULL == connection || NULL == connection->channelConfig )
+ continue;
+ if( 0xFFFFFFFF != connection->splittedSourceHandle )
+ {
+ handles[amount++] = connection->splittedSourceHandle;
+ for( int j = 0; j < node->GetAmountOfConnections(); j++ )
+ {
+ if( i == j )
+ continue;
+ CNodeConnectionEntry *otherConn = node->GetConnectionByIndex( j );
+ if( ( otherConn != NULL ) && ( otherConn->splittedSourceHandle == connection->
+ splittedSourceHandle ) )
+ {
+ otherConn->splittedSourceHandle = 0xFFFFFFFF;
+ }
+ }
+ connection->splittedSourceHandle = 0xFFFFFFFF;
+ }
+ }
+ if( amount != 0 )
+ {
+ device->ResourceDestroyV3( nodeAddress, amount, handles, 0 );
+ }
+ }
+ while( amount != 0 );
+ }
+}
+
+void CNetwork::DestroyAllResources()
+{
+ CNetworkDevice *device;
+ uint16_t nodeAmount = CNodeEntry::GetAmountOfNodeEntries();
+ for( int i = 0; i < nodeAmount; i++ )
+ {
+ CNodeEntry *node = CNodeEntry::GetNodeEntry( i );
+ if( NULL == node )
+ continue;
+ CNetworkDevice *device = GetNetworkDevice( node->deviceInstance );
+ uint16_t nodeAddress = node->nodeAddress;
+ DestroyAllResources( device, nodeAddress );
+ }
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ device = allNetworkDevices[i];
+ if( NULL != device )
+ {
+ sem_wait( &vodXmlMutex );
+ if( NULL != vodXml )
+ {
+ sem_post( &vodXmlMutex );
+ if( device->IsTimingMaster() )
+ {
+ ConsolePrintf( PRIO_MEDIUM, "DestroyAllResources, Performing MOST Shutdown index: %d\n",
+ device->GetDeviceIndex() );
+ device->ToggleNotOk();
+ device->SetNetstate( NetworkState_ShutdownInProgress );
+ device->MostNetworkShutdownV3();
+ }
+ }
+ else
+ sem_post( &vodXmlMutex );
+ }
+ }
+ PRINT_ALL_INFOS();
+}
+
+void CNetwork::CloseAllNetworkDevices()
+{
+ DestroyAllResources();
+ CNetworkDevice *device;
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ device = allNetworkDevices[i];
+ if( NULL != device )
+ {
+ ConsolePrintf( PRIO_MEDIUM, "CloseAllNetworkDevices, Closing device index: %d\n",
+ device->GetDeviceIndex() );
+ device->Close();
+ }
+ }
+ allNetworkDevices.RemoveAll(true);
+ connectionBitMask = 0;
+}
+
+void CNetwork::FindNewNetworkDevices()
+{
+ sem_wait( &vodXmlMutex );
+ if( NULL == vodXml )
+ {
+ sem_post( &vodXmlMutex );
+ return;
+ }
+ bool success = false;
+ bool infoQueried = false;
+ uint8_t *controlRxAddress = NULL;
+ uint8_t *controlTxAddress = NULL;
+ uint32_t *apiVersion = NULL;
+ SocketPort_t *hwPort = NULL;
+ bool *isTimingMaster = NULL;
+ uint32_t *asyncBW = NULL;
+ uint8_t serverNum = 0;
+ for( uint8_t devInstance = 0; devInstance < MAX_MOST_DEVICES; devInstance++ )
+ {
+ if( 0 != ( connectionBitMask & ( 1 << devInstance ) ) )
+ continue;
+
+ if( !infoQueried )
+ infoQueried = vodXml->GetLocalInicConfigurations( &controlRxAddress, &controlTxAddress, &apiVersion,
+ &hwPort, &isTimingMaster, &asyncBW, &serverNum );
+
+ if( !infoQueried )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Can not parse XML file to configure server device"RESETCOLOR"\n" );
+ sem_post( &vodXmlMutex );
+ return;
+ }
+ for( uint8_t conIndex = 0; conIndex < serverNum; conIndex++ )
+ {
+ if( ( ( PORT_MLB == hwPort[conIndex] ) && ExistsMlbDeviceInstance( devInstance ) )
+ || ( ( PORT_USB == hwPort[conIndex] ) && ExistsUsbDeviceInstance( devInstance ) ) )
+ {
+ connectionBitMask += ( 1 << devInstance );
+ ConsolePrintf( PRIO_MEDIUM, "=======Server %d device uses %s, INIC API V%d=======\n",
+ devInstance, ( PORT_USB == hwPort[conIndex] ? "USB" : PORT_MLB == hwPort[conIndex] ? "MLB" :
+ "UNKNOWN" ), apiVersion[conIndex] );
+ ConsolePrintf( PRIO_MEDIUM, "Opening device instance %d\n", devInstance );
+ CNetworkDevice *newDevice = new CNetworkDevice( devInstance,
+ apiVersion[conIndex], isTimingMaster[conIndex], asyncBW[conIndex], promiscuous );
+ switch( hwPort[conIndex] )
+ {
+ case PORT_USB:
+ success = newDevice->OpenUsb( controlRxAddress[conIndex], controlTxAddress[conIndex] );
+ break;
+ case PORT_MLB:
+ success = newDevice->OpenMlb( controlRxAddress[conIndex], controlTxAddress[conIndex] );
+ break;
+ default:
+ success = false;
+ break;
+ }
+ if( success )
+ {
+ allNetworkDevices.PushBack( newDevice );
+ newDevice->AddListener( this );
+ }
+ else
+ {
+ if( ( PORT_USB == hwPort[conIndex] ) && ( apiVersion[conIndex] < 3 ) )
+ ConsolePrintf( PRIO_ERROR, RED"Failed to open device instance %d"\
+ RESETCOLOR"\n", devInstance );
+ delete newDevice;
+ }
+ }
+ }
+ }
+ if( NULL != controlRxAddress )
+ free( controlRxAddress );
+ if( NULL != controlTxAddress )
+ free( controlTxAddress );
+ if( NULL != apiVersion )
+ free( apiVersion );
+ if( NULL != hwPort )
+ free( hwPort );
+ sem_post( &vodXmlMutex );
+}
+
+void CNetwork::TryToCreateRoute( uint32_t devInstance, bool mostIsTx, void *e, void *t )
+{
+ if( NULL == e || NULL == t )
+ return;
+ CNodeEntry *entry = ( CNodeEntry * )e;
+ CRouteTerminal *terminal = ( CRouteTerminal * )t;
+ CSafeVector<CRouteTerminal *> connectedTerminals;
+
+ sem_wait( &vodXmlMutex );
+ bool found = vodXml->GetRouteTerminals( terminal, connectedTerminals );
+ sem_post( &vodXmlMutex );
+ if( !found )
+ return;
+ CNodeEntry *oppositeEntry = NULL;
+ for( uint32_t i = 0; i < connectedTerminals.Size(); i++ )
+ {
+ if( NULL != ( oppositeEntry = CNodeEntry::GetNodeEntry( devInstance, connectedTerminals[i]->deviceType,
+ connectedTerminals[i]->instance ) ) )
+ {
+ if( mostIsTx )
+ ConnectSourceToSink( entry, oppositeEntry, terminal->channelId, connectedTerminals[i]->channelId );
+ else
+ ConnectSourceToSink( oppositeEntry, entry, connectedTerminals[i]->channelId, terminal->channelId );
+ }
+ delete connectedTerminals[i];
+ }
+}
+
+void CNetwork::TryToConnectSockets( uint32_t devInstance, uint16_t nodeAddr, uint32_t channelId )
+{
+ CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddr );
+ if( NULL != entry )
+ {
+ CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( channelId, true );
+ CNetworkDevice *device = GetNetworkDevice( devInstance );
+ CChannelConfiguration *config = connection->channelConfig;
+ sem_wait( &vodXmlMutex );
+ uint32_t deviceApi = vodXml->GetDeviceApi( connection->channelConfig->deviceType );
+ sem_post( &vodXmlMutex );
+ if( ( NULL != connection ) && ( NULL != device ) && ( NULL != config ) )
+ {
+ CRouteTerminal terminal;
+ terminal.channelId = channelId;
+ terminal.deviceType = entry->deviceType;
+ terminal.instance = CNodeEntry::GetTerminalInstance( devInstance, nodeAddr, entry->deviceType );
+
+ if( ( NodeConnection_Used == connection->inSocketState )
+ && ( NodeConnection_Used == connection->outSocketState )
+ && ( NodeConnection_NotUsed == connection->connectedSocketState ) )
+ {
+ if( deviceApi > 3 )
+ {
+ ConsolePrintf(
+ PRIO_ERROR, RED"TryToConnectSockets found unknown device API version: %d"RESETCOLOR"\n",
+ deviceApi );
+ return;
+ }
+ connection->connectedSocketState = NodeConnection_Pending_Up;
+ if( 1 == deviceApi )
+ {
+ device->ConnectSocketsV1( nodeAddr, connection->inHandle, connection->outHandle, channelId );
+ }
+ else if( ( 2 == deviceApi ) || ( 3 == deviceApi ) )
+ {
+ uint32_t offset = config->inSocket.splittedOffset;
+ if( 0xFFFFFFFF == offset )
+ {
+ offset = config->outSocket.splittedOffset;
+ if( 0xFFFFFFFF == offset )
+ offset = 0;
+ }
+ device->ConnectSocketsV3( nodeAddr, config->outSocket.type, connection->inHandle,
+ connection->outHandle, offset, channelId );
+ }
+ TryToCreateRoute( devInstance, true, entry, &terminal );
+ }
+ else if( ( NodeConnection_NotUsed == connection->inSocketState )
+ && ( NodeConnection_Used == connection->outSocketState )
+ && ( PORT_MOST == config->inSocket.port ) )
+ {
+ TryToCreateRoute( devInstance, false, entry, &terminal );
+ }
+ }
+ }
+ PRINT_ALL_INFOS();
+}
+
+void CNetwork::TryToCloseExistingMostConnection( void *inNode, uint32_t inChannelId, void *outNode,
+ uint32_t outChannelId )
+{
+ if( ( NULL == inNode ) || ( NULL == outNode ) )
+ return;
+
+ for( uint8_t i = 0; i < 2; i++ )
+ {
+ CNodeConnectionEntry *closeEntry = NULL;
+ switch( i )
+ {
+ case 0:
+ closeEntry = ( ( CNodeEntry * )outNode )->GetConnectionByChannelId( outChannelId, false );
+ break;
+ case 1:
+ closeEntry = ( ( CNodeEntry * )inNode )->GetConflictingConnection( inChannelId,
+ ( ( CNodeEntry * )outNode ) );
+ break;
+ }
+ if( NULL == closeEntry || NULL == closeEntry->channelConfig
+ || NULL == closeEntry->parentNode )
+ continue;
+
+ if( ( NodeConnection_Used == closeEntry->inSocketState ) &&
+ ( NodeConnection_Used == closeEntry->connectedSocketState ) &&
+ ( PORT_MOST == closeEntry->channelConfig->inSocket.port ) )
+ {
+ uint8_t oppInst = closeEntry->parentNode->deviceInstance;
+ CNetworkDevice *oppDevice = GetNetworkDevice( oppInst );
+ if( NULL != oppDevice )
+ {
+ uint16_t oppNodeAddress = closeEntry->parentNode->nodeAddress;
+ uint32_t oppApiVer = closeEntry->parentNode->deviceType;
+ uint32_t oppConHandle = closeEntry->connectHandle;
+ uint32_t oppInHandle = closeEntry->inHandle;
+ uint32_t oppChannelId = closeEntry->channelId;
+
+ closeEntry->connectedSocketState = NodeConnection_Pending_Down;
+ closeEntry->inSocketState = NodeConnection_Pending_Down;
+
+ if( 1 == oppApiVer )
+ {
+ oppDevice->DisconnectSocketsV1( oppNodeAddress, oppConHandle, oppChannelId );
+ oppDevice->DestroySocketV1( oppNodeAddress, oppInHandle, oppChannelId );
+ }
+ else if( 2 == oppApiVer || 3 == oppApiVer )
+ {
+ uint16_t a[2];
+ a[0] = oppConHandle;
+ a[1] = oppInHandle;
+ oppDevice->ResourceDestroyV3( oppNodeAddress, 2, a, oppChannelId );
+ }
+ }
+ }
+ }
+ PRINT_ALL_INFOS();
+}
+
+void CNetwork::RaiseAvailable( void *con )
+{
+ CNodeConnectionEntry *connection = ( CNodeConnectionEntry * )con;
+ if( ( NULL != connection )
+ && ( NULL != connection->parentNode )
+ && ( NULL != connection->channelConfig )
+ )
+ {
+ uint32_t blockWidth = connection->channelConfig->outSocket.blockWidth;
+ if( 0xFFFFFFFF == blockWidth )
+ blockWidth = connection->channelConfig->inSocket.blockWidth;
+
+ uint16_t xact = 0;
+ if ( PORT_USB == connection->channelConfig->inSocket.port )
+ xact = connection->channelConfig->inSocket.packetsPerTransaction;
+ else if ( PORT_USB == connection->channelConfig->outSocket.port )
+ xact = connection->channelConfig->outSocket.packetsPerTransaction;
+
+ uint32_t devInst = CNodeEntry::GetTerminalInstance( connection->parentNode->deviceInstance,
+ connection->parentNode->nodeAddress, connection->parentNode->deviceType );
+ for( uint32_t i = 0; i < allListeners.Size(); i++ )
+ {
+ int offset = -1;
+ int maxBW = -1;
+ if( 0xFFFFFFFF != connection->channelConfig->inSocket.splittedOffset )
+ {
+ offset = connection->channelConfig->inSocket.splittedOffset;
+ maxBW = connection->channelConfig->inSocket.subbufferSize;
+ }
+ else if( 0xFFFFFFFF != connection->channelConfig->outSocket.splittedOffset )
+ {
+ offset = connection->channelConfig->outSocket.splittedOffset;
+ maxBW = connection->channelConfig->outSocket.subbufferSize;
+ }
+ allListeners[i]->OnChannelAvailable( connection->parentNode->macAddress,
+ connection->parentNode->deviceType, devInst, connection->channelId,
+ connection->parentNode->deviceInstance, connection->channelConfig->outSocket.type,
+ blockWidth, ( PORT_MOST == connection->channelConfig->outSocket.port ), ( NodeConnection_Used ==
+ connection->inSocketState ), ( NodeConnection_Used == connection->outSocketState ),
+ ( NodeConnection_Used == connection->connectedSocketState ), connection->bufferSize,
+ connection->mostConnectionLabel, offset, maxBW, xact, connection->deviceName );
+ }
+ }
+}
+
+void CNetwork::RaiseUnavailable( void *con )
+{
+ CNodeConnectionEntry *connection = ( CNodeConnectionEntry * )con;
+ if( ( NULL != connection )
+ && ( NULL != connection->parentNode )
+ && ( NULL != connection->channelConfig )
+ && ( NULL != connection->parentNode->macAddress )
+ )
+ {
+ for( uint32_t i = 0; i < allListeners.Size(); i++ )
+ {
+ allListeners[i]->OnChannelUnavailable( connection->parentNode->macAddress, connection->channelId,
+ connection->parentNode->deviceInstance );
+ }
+ }
+}
+
+CNetworkDevice *CNetwork::GetNetworkDevice( uint32_t devInstance )
+{
+ CNetworkDevice *device = NULL;
+ for( uint32_t i = 0; i < allNetworkDevices.Size(); i++ )
+ {
+ if( devInstance == allNetworkDevices[i]->GetDeviceIndex() )
+ {
+ device = allNetworkDevices[i];
+ break;
+ }
+ }
+ return device;
+}
+
+CMacAddr *CNetwork::SetMacAddress( CNetworkDevice *device, uint32_t devInstance, uint16_t nodeAddress,
+ uint8_t inicApiVersion )
+{
+ if( NULL == device )
+ return NULL;
+ CMacAddr *mac = new CMacAddr( devInstance, nodeAddress );
+ if( NULL == mac )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"Failed to instance CMacAddr object"RESETCOLOR"\n" );
+ return NULL;
+ }
+ ConsolePrintf( PRIO_MEDIUM,
+ "Creating local MAC for deviceInstance:%d: nodeAddress:0x%X, MAC-Address:%02X-%02X-%02X-%02X-%02X-%02X)\n",
+ devInstance, nodeAddress, ( *mac )[0], ( *mac )[1], ( *mac )[2], ( *mac )[3], ( *mac )[4], ( *mac )[5] );
+
+ switch( inicApiVersion )
+ {
+ case 1:
+ device->SetMostMacAddressV1( nodeAddress, ( *mac )[0], ( *mac )[1], ( *mac )[2], ( *mac )[3], ( *mac )[4],
+ ( *mac )[5], false );
+ break;
+ case 2:
+ device->SetMostMacAddressV3( nodeAddress, ( *mac )[0], ( *mac )[1], ( *mac )[2], ( *mac )[3], ( *mac )[4],
+ ( *mac )[5] );
+ break;
+ case 3:
+ device->SetMostMacAddressV3( nodeAddress, ( *mac )[0], ( *mac )[1], ( *mac )[2], ( *mac )[3], ( *mac )[4],
+ ( *mac )[5] );
+ break;
+ default:
+ ConsolePrintf(
+ PRIO_ERROR, RED"Can not set local MAC, because device API version (%d) is unknown"RESETCOLOR"\n",
+ inicApiVersion );
+ delete mac;
+ mac = NULL;
+ break;
+ }
+ return mac;
+}
+
+bool CNetwork::ConnectSourceToSink( void *mostTxNode, void *mostRxNode, uint32_t sourceChannelId,
+ uint32_t sinkChannelId )
+{
+ bool success = false;
+ PRINT_ALL_INFOS();
+ if( ( NULL != mostTxNode ) && ( NULL != mostRxNode ) )
+ {
+ CNodeEntry *txNode = ( CNodeEntry * )mostTxNode;
+ CNodeEntry *rxNode = ( CNodeEntry * )mostRxNode;
+ CNodeConnectionEntry *inConnection = txNode->GetConnectionByChannelId( sourceChannelId, false );
+ CNodeConnectionEntry *outConnection = rxNode->GetConnectionByChannelId( sinkChannelId, false );
+ CNetworkDevice *outDevice = GetNetworkDevice( rxNode->deviceInstance );
+ if( ( NULL != inConnection ) && ( NULL != outConnection ) && ( NULL != outDevice )
+ && ( NULL != outConnection->channelConfig ) && ( 0xFFFFFFFF != inConnection->mostConnectionLabel ) )
+ {
+ if( ( NodeConnection_Used == inConnection->outSocketState )
+ && ( NodeConnection_NotUsed == outConnection->inSocketState ) )
+ {
+ uint32_t connectionLabel = inConnection->mostConnectionLabel;
+ sem_wait( &vodXmlMutex );
+ uint32_t inApiVer = vodXml->GetDeviceApi( txNode->deviceType );
+ uint32_t outApiVer = vodXml->GetDeviceApi( rxNode->deviceType );
+ sem_post( &vodXmlMutex );
+ ConsolePrintf( PRIO_MEDIUM,
+ BLUE"CNetwork::ConnectSourceToSink Connection Label:0x%X, IN-API-Ver:%d, OUT-API-Ver:%d, devIndex:%d, address:0x%X"RESETCOLOR"\n",
+ connectionLabel, inApiVer, outApiVer, rxNode->deviceInstance,
+ rxNode->nodeAddress );
+ TryToCloseExistingMostConnection( txNode, sourceChannelId, rxNode, sinkChannelId );
+ if( 1 == outApiVer )
+ {
+ outDevice->CreateMostSocketV1( rxNode->nodeAddress, outConnection->channelConfig->inSocket.type,
+ EPDIR_IN, connectionLabel, outConnection->channelConfig->inSocket.blockWidth, sinkChannelId );
+ success = true;
+ }
+ else if( 2 == outApiVer || 3 == outApiVer )
+ {
+ outDevice->CreateMostSocketV3( rxNode->nodeAddress, outConnection->channelConfig->inSocket.type,
+ EPDIR_IN, connectionLabel, outConnection->channelConfig->inSocket.blockWidth, sinkChannelId );
+ success = true;
+ }
+ if( success )
+ {
+ outConnection->inSocketState = NodeConnection_Pending_Up;
+ outConnection->mostConnectionLabel = connectionLabel;
+ }
+ }
+ }
+ }
+ else
+ {
+ ConsolePrintf(
+ PRIO_ERROR, RED"CNetwork::SetSinkToChannel failed to resolve given MAC addresses"RESETCOLOR"\n" );
+ }
+ PRINT_ALL_INFOS();
+ return success;
+}
+
+void CNetwork::RaiseUknownConnection( uint32_t devInstance, uint16_t nodeAddress, EPDataType_t dType )
+{
+ CNodeEntry *entry = CNodeEntry::GetNodeEntry( devInstance, nodeAddress );
+ CNodeConnectionEntry *connection = entry->GetConnectionByChannelId( 0xFF, true );
+ entry->macAddress = new CMacAddr( devInstance, nodeAddress );
+ connection->channelConfig = new CChannelConfiguration();
+ connection->channelConfig->inSocket.type = dType;
+ connection->channelConfig->outSocket.type = dType;
+ RaiseAvailable( connection );
+}
+
+void CNetwork::ShutdownMost( CNetworkDevice *device )
+{
+ if( NULL == device )
+ return;
+ device->ClearAllPendingActions();
+ device->SetNetstate( NetworkState_ShutdownInProgress );
+ device->MostNetworkShutdownV3();
+}
+
+void CNetwork::ShutdownMostBecauseOfErrors( CNetworkDevice *device )
+{
+ if (retryCounter < 5)
+ {
+ retryExecTime = GetTickCount();
+ retryCounter++;
+ ConsolePrintf(
+ PRIO_ERROR, RED"Restart MOST because of resources allocation /"\
+ " configuration problems, retry count=%d"RESETCOLOR"\n", retryCounter );
+ ShutdownMost( device );
+ }
+} \ No newline at end of file
diff --git a/Src/Network/NodeDatabase.cpp b/Src/Network/NodeDatabase.cpp
new file mode 100644
index 0000000..d53d2d1
--- /dev/null
+++ b/Src/Network/NodeDatabase.cpp
@@ -0,0 +1,287 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include "Console.h"
+#include "NodeDatabase.h"
+
+CSafeVector<CNodeEntry *> CNodeEntry::allNodes;
+
+CNodeConnectionEntry::CNodeConnectionEntry( CNodeEntry *parent ) : parentNode( parent ), channelConfig( NULL ),
+ channelId( 0xFFFFFFFF ), inHandle( 0xFFFFFFFF ),
+ outHandle( 0xFFFFFFFF ),
+ connectHandle( 0xFFFFFFFF ),
+ splittedSourceHandle( 0xFFFFFFFF ),
+ mostConnectionLabel( 0xFFFFFFFF ),
+ inSocketState( NodeConnection_NotUsed ),
+ outSocketState( NodeConnection_NotUsed ),
+ connectedSocketState( NodeConnection_NotUsed ),
+ bufferSize( -1 )
+{
+ memset( deviceName, 0, sizeof( deviceName ) );
+};
+
+CNodeConnectionEntry::~CNodeConnectionEntry()
+{
+ if( NULL != channelConfig )
+ {
+ delete channelConfig;
+ channelConfig = NULL;
+ }
+}
+
+CNodeEntry::CNodeEntry() : deviceInstance( 0xFF ), nodeAddress( 0xFFFF ), deviceType( 0xFFFF ), macAddress( NULL ),
+ isTsiPortOpened(false), isMlbPortOpened( false ), isUsbPortOpened( false ), isI2SPortOpened( false )
+{
+}
+
+CNodeEntry::~CNodeEntry()
+{
+ if( NULL != macAddress )
+ delete macAddress;
+}
+
+uint16_t CNodeEntry::GetAmountOfNodeEntries()
+{
+ return allNodes.Size();
+}
+
+CNodeEntry *CNodeEntry::GetNodeEntry( uint16_t index )
+{
+ return allNodes[index];
+}
+
+CNodeEntry *CNodeEntry::GetNodeEntry( uint8_t deviceInstance, uint16_t nodeAddress )
+{
+ CNodeEntry *entry = NULL;
+ for( uint32_t i = 0; i < allNodes.Size(); i++ )
+ {
+ if( ( allNodes[i]->deviceInstance == deviceInstance )
+ && ( allNodes[i]->nodeAddress == nodeAddress ) )
+ {
+ entry = allNodes[i];
+ break;
+ }
+ }
+ if( NULL == entry )
+ {
+ entry = new CNodeEntry();
+ entry->deviceInstance = deviceInstance;
+ entry->nodeAddress = nodeAddress;
+ allNodes.PushBack( entry );
+ }
+ return entry;
+}
+
+CNodeEntry *CNodeEntry::GetNodeEntry( CMacAddr *macAddress )
+{
+ if( NULL == macAddress )
+ return NULL;
+ CNodeEntry *entry = NULL;
+ for( uint32_t i = 0; i < allNodes.Size(); i++ )
+ {
+ CNodeEntry *node = allNodes[i];
+ if( ( NULL != node->macAddress ) && ( *node->macAddress == *macAddress ) )
+ {
+ entry = node;
+ break;
+ }
+ }
+ return entry;
+}
+
+CNodeEntry *CNodeEntry::GetNodeEntry( uint8_t deviceInstance, uint32_t deviceType, uint32_t terminalInstance )
+{
+ uint32_t inst = 0;
+ CNodeEntry *entry = NULL;
+ for( uint32_t i = 0; i < allNodes.Size(); i++ )
+ {
+ CNodeEntry *node = allNodes[i];
+ if( ( allNodes[i]->deviceInstance == deviceInstance )
+ && ( allNodes[i]->deviceType == deviceType ) )
+ {
+ if( inst == terminalInstance )
+ {
+ entry = node;
+ break;
+ }
+ else
+ {
+ ++inst;
+ }
+ }
+ }
+ return entry;
+}
+
+uint32_t CNodeEntry::GetTerminalInstance( uint8_t deviceInstance, uint16_t nodeAddress, uint32_t deviceType )
+{
+ uint32_t terminalInst = 0;
+ for( uint32_t i = 0; i < allNodes.Size(); i++ )
+ {
+ if( ( allNodes[i]->deviceInstance == deviceInstance )
+ && ( allNodes[i]->deviceType == deviceType ) )
+ {
+ if( ( allNodes[i]->nodeAddress == nodeAddress ) )
+ break;
+ else
+ ++terminalInst;
+ }
+ }
+ return terminalInst;
+}
+
+void CNodeEntry::DeleteAllNodeEntries()
+{
+ allNodes.RemoveAll(true);
+}
+
+void CNodeEntry::DeleteNodeEntry( uint16_t index )
+{
+ CNodeEntry *ent = allNodes[index];
+ if( NULL == ent )
+ return;
+
+ allNodes.Remove(ent);
+ delete ent;
+}
+
+const char *CNodeEntry::GetConnectionStateString( NodeConnectionState_t conState )
+{
+ switch( conState )
+ {
+ case NodeConnection_NotUsed:
+ return "Idle";
+ case NodeConnection_Pending_Up:
+ return "Pending-Up";
+ case NodeConnection_Pending_Down:
+ return "Pending-Down";
+ case NodeConnection_Used:
+ return "Established";
+ default:
+ return "Unknown State";
+ }
+}
+
+void CNodeEntry::PrintAllInformations()
+{
+ ConsolePrintfStart( PRIO_LOW, "==================================================================\n" );
+ for( uint32_t i = 0; i < allNodes.Size(); i++ )
+ {
+ CNodeEntry *entry = allNodes[i];
+ ;
+ if( NULL != entry )
+ {
+ ConsolePrintfContinue( "Inst:%d, NodeAddr:0x%X, DevType:0x%X, MAC:%s, open:%d\n", entry->deviceInstance,
+ entry->nodeAddress, entry->deviceType, ( NULL != entry->macAddress ? entry->macAddress->ToString() :
+ "None" ), ( entry->isUsbPortOpened || entry->isMlbPortOpened ) );
+ for( uint32_t j = 0; j < entry->GetAmountOfConnections(); j++ )
+ {
+ CNodeConnectionEntry *con = entry->GetConnectionByIndex( j );
+ ConsolePrintfContinue(
+ "Id:%d, inHandle:0x%X, outHandle:0x%X, conHandle:0x%X, conLabel:0x%X, inState:%s, outState:%s, conState:%s, bufferSize:%d, name:%s\n", con->channelId, con->inHandle, con->outHandle, con->connectHandle, con->mostConnectionLabel, GetConnectionStateString( con->inSocketState ), GetConnectionStateString( con->outSocketState ), GetConnectionStateString( con->connectedSocketState ), con->bufferSize, con->deviceName );
+ }
+ }
+ if( i < allNodes.Size() - 1 )
+ ConsolePrintfContinue( "------------------------------------------------------------------\n" );
+ }
+ ConsolePrintfExit( "==================================================================\n" );
+}
+
+uint16_t CNodeEntry::GetAmountOfConnections()
+{
+ return allConnections.Size();
+}
+
+CNodeConnectionEntry *CNodeEntry::GetConnectionByIndex( uint16_t index )
+{
+ return allConnections[index];
+}
+
+CNodeConnectionEntry *CNodeEntry::GetConnectionByChannelId( uint32_t channelId, bool createNewIfUnknown )
+{
+ CNodeConnectionEntry *entry = NULL;
+ for( uint32_t i = 0; i < allConnections.Size(); i++ )
+ {
+ if( allConnections[i]->channelId == channelId )
+ {
+ entry = allConnections[i];
+ break;
+ }
+ }
+ if( createNewIfUnknown && NULL == entry )
+ {
+ entry = new CNodeConnectionEntry( this );
+ entry->channelId = channelId;
+ allConnections.PushBack( entry );
+ }
+ return entry;
+}
+
+CNodeConnectionEntry *CNodeEntry::GetConflictingConnection( uint32_t channelId, CNodeEntry *opposite )
+{
+ if( NULL == opposite )
+ return NULL;
+ if( opposite->deviceInstance != deviceInstance )
+ return NULL;
+ CNodeConnectionEntry *entry = NULL;
+ uint32_t connectionLabel = 0xFFFFFFFF;
+ for( uint32_t i = 0; i < allConnections.Size(); i++ )
+ {
+ if( allConnections[i]->channelId == channelId )
+ {
+ connectionLabel = allConnections[i]->mostConnectionLabel;
+ break;
+ }
+ }
+ if( 0xFFFFFFFF != connectionLabel )
+ {
+ for( uint32_t i = 0; i < opposite->allConnections.Size(); i++ )
+ {
+ if( opposite->allConnections[i]->mostConnectionLabel == connectionLabel )
+ {
+ entry = opposite->allConnections[i];
+ break;
+ }
+ }
+ }
+ return entry;
+}
+
+void CNodeEntry::DeleteConnection( uint32_t channelId )
+{
+ uint32_t index = 0xFFFFFFFF;
+ for( uint32_t i = 0; i < allConnections.Size(); i++ )
+ {
+ if( allConnections[i]->channelId == channelId )
+ {
+ index = i;
+ }
+ }
+ if( index >= allNodes.Size() )
+ return;
+ CNodeConnectionEntry *ent = allConnections[index];
+ allConnections.Remove(ent);
+ delete ent;
+}
diff --git a/Src/Network/NodeDatabase.h b/Src/Network/NodeDatabase.h
new file mode 100644
index 0000000..16eb863
--- /dev/null
+++ b/Src/Network/NodeDatabase.h
@@ -0,0 +1,379 @@
+/*
+ * 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 CNodeEntry and the CNodeConnectionEntry class.
+ */
+/*----------------------------------------------------------*/
+#ifndef NODEDATABASE_H
+#define NODEDATABASE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "SafeVector.h"
+#include "VodXml.h"
+#include "MacAddr.h"
+
+class CNodeEntry;
+class CNodeConnectionEntry;
+
+/*----------------------------------------------------------*/
+/*! \brief Enumeration describing the state of a Node socket
+ */
+/*----------------------------------------------------------*/
+typedef enum NodeConnectionState_tag
+{
+ NodeConnection_NotUsed,
+ NodeConnection_Pending_Up,
+ NodeConnection_Pending_Down,
+ NodeConnection_Used
+} NodeConnectionState_t;
+
+/*----------------------------------------------------------*/
+/*! \brief Storage class holding informations of a specific MOST connection (Ports)
+ */
+/*----------------------------------------------------------*/
+class CNodeConnectionEntry
+{
+public:
+ /*----------------------------------------------------------*/
+ /*! \brief Pointer to the device, which this connection belongs to.
+ */
+ /*----------------------------------------------------------*/
+ CNodeEntry *parentNode;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Pointer to the XML generated configuration, holding the user specific part of this connection.
+ */
+ /*----------------------------------------------------------*/
+ CChannelConfiguration *channelConfig;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Identifier determinating the connection based on the XML configuration.
+ */
+ /*----------------------------------------------------------*/
+ uint32_t channelId;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief In-Handle provided from INIC when the In-Socket was created
+ */
+ /*----------------------------------------------------------*/
+ uint32_t inHandle;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Out-Handle provided from INIC when the Out-Socket was created
+ */
+ /*----------------------------------------------------------*/
+ uint32_t outHandle;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Connection-Handle provided from INIC when the In- and the Out-Socket were connected.
+ */
+ /*----------------------------------------------------------*/
+ uint32_t connectHandle;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief If this connection uses combiner or splitter, this handle points to the source / sink of the splitter / combiner.
+ * \note The idea of storing this handle, is only for cleanup purposes.
+ * \warning Do not use this handle for creating connections.
+ */
+ /*----------------------------------------------------------*/
+ uint32_t splittedSourceHandle;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Connection-Handle provided from INIC when the MOST-Socket was created.
+ */
+ /*----------------------------------------------------------*/
+ uint32_t mostConnectionLabel;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief The state of the In-Socket
+ */
+ /*----------------------------------------------------------*/
+ NodeConnectionState_t inSocketState;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief The state of the Out-Socket
+ */
+ /*----------------------------------------------------------*/
+ NodeConnectionState_t outSocketState;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief The connection state between In-Socket and Out-Socket
+ */
+ /*----------------------------------------------------------*/
+ NodeConnectionState_t connectedSocketState;
+
+ /*----------------------------------------------------------*/
+ /*! \brief The used buffer size for this connection.
+ * \note bufferSize is -1 in case, there were no buffers configured.
+ */
+ /*----------------------------------------------------------*/
+ int32_t bufferSize;
+
+ /*----------------------------------------------------------*/
+ /*! \brief The Linux character device name, when this connection belongs to a local connection. May be strlen of 0.
+ */
+ /*----------------------------------------------------------*/
+ char deviceName[64];
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Constructor of CNodeConnectionEntry.
+ * \param Pointer to the device this connection belongs to.
+ */
+ /*----------------------------------------------------------*/
+ CNodeConnectionEntry( CNodeEntry *parentNode );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Destructor of CNodeConnectionEntry.
+ */
+ /*----------------------------------------------------------*/
+ ~CNodeConnectionEntry();
+};
+
+/*----------------------------------------------------------*/
+/*! \brief Storage class holding information of a specific MOST device
+ */
+/*----------------------------------------------------------*/
+class CNodeEntry
+{
+private:
+ static CSafeVector<CNodeEntry *> allNodes;
+ CSafeVector<CNodeConnectionEntry *> allConnections;
+
+ CNodeEntry();
+ static const char *GetConnectionStateString( NodeConnectionState_t state );
+public:
+ ~CNodeEntry();
+
+ /*----------------------------------------------------------*/
+ /*! \brief MOST instance. 0 for the first instance. If the server has multiple MOST devices, this value will be increased.
+ */
+ /*----------------------------------------------------------*/
+ uint8_t deviceInstance;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief The unique address of the MOST device.
+ */
+ /*----------------------------------------------------------*/
+ uint16_t nodeAddress;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief The type of the device (derived from the group address), as described in the XML configuration.
+ */
+ /*----------------------------------------------------------*/
+ uint16_t deviceType;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief The unique MAC address of the device.
+ */
+ /*----------------------------------------------------------*/
+ CMacAddr *macAddress;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Determines if the TSI port is opened.
+ * \return true, if the port is opened. false
+ */
+ /*----------------------------------------------------------*/
+ bool isTsiPortOpened;
+
+ /*----------------------------------------------------------*/
+ /*! \brief Determines if the MLB port is opened.
+ * \return true, if the port is opened. false
+ */
+ /*----------------------------------------------------------*/
+ bool isMlbPortOpened;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Determines if the USB port is opened.
+ * \return true, if the port is opened. false
+ */
+ /*----------------------------------------------------------*/
+ bool isUsbPortOpened;
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Determines if the USB port A is opened.
+ * \return true, if the port is opened. false
+ */
+ /*----------------------------------------------------------*/
+ bool isI2SPortOpened;
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets the amount of available MOST devices.
+ * \return The number of MOST devices.
+ */
+ /*----------------------------------------------------------*/
+ static uint16_t GetAmountOfNodeEntries();
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets an instance of CNodeEntry by the given instance index
+ * \param index - starting at 0 for the first instance. "GetAmountOfNodeEntries() - 1" for the last instance.
+ * \return The requested instance, when successful. Otherwise NULL pointer.
+ */
+ /*----------------------------------------------------------*/
+ static CNodeEntry *GetNodeEntry( uint16_t index );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets an instance of CNodeEntry by the given MOST instance and the unique node address of the device.
+ * \param deviceInstance - MOST instance id, starting at 0 for the first MOST ring. When the server have multiple MOST devices,
+ * This value may be above 0.
+ * \param nodeAddress - The MOST node address of the specific device (0x100 e.g.).
+ * \return The requested instance, when successful. Otherwise NULL pointer.
+ */
+ /*----------------------------------------------------------*/
+ static CNodeEntry *GetNodeEntry( uint8_t deviceInstance, uint16_t nodeAddress );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets an instance of CNodeEntry by the given unique MAC address of the device.
+ * \param macAddress - Unique MAC address of the device
+ * \return The requested instance, when successful. Otherwise NULL pointer.
+ */
+ /*----------------------------------------------------------*/
+ static CNodeEntry *GetNodeEntry( CMacAddr *macAddress );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets an instance of CNodeEntry by the given device type and terminal instance
+ * \param deviceInstance - MOST instance id, starting at 0 for the first MOST ring. When the server have multiple MOST devices,
+ * This value may be above 0.
+ * \param deviceType - The type of the device (derived from the group address), as described in the XML configuration.
+ * \param terminalInstance - The instance of the terminal, starting at 0 for the first terminal.
+ *
+ * \return The requested instance, when successful. Otherwise NULL pointer.
+ */
+ /*----------------------------------------------------------*/
+ static CNodeEntry *GetNodeEntry( uint8_t deviceInstance, uint32_t deviceType, uint32_t terminalInstance );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets the terminal instance number for the given device type.
+ * \param deviceInstance - MOST instance id, starting at 0 for the first MOST ring. When the server have multiple MOST devices,
+ * This value may be above 0.
+ * \param nodeAddress - The MOST node address of the specific device (0x100 e.g.).
+ * \param deviceType - The type of the device (derived from the group address), as described in the XML configuration.
+ *
+ * \return The requested instance, when successful. Otherwise NULL pointer.
+ */
+ /*----------------------------------------------------------*/
+ static uint32_t GetTerminalInstance( uint8_t deviceInstance, uint16_t nodeAddress, uint32_t deviceType );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Deleting all informations of any device.
+ */
+ /*----------------------------------------------------------*/
+ static void DeleteAllNodeEntries();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Deleting all informations of a specific device.
+ * \param index - starting at 0 for the first instance. "GetAmountOfNodeEntries() - 1" for the last instance.
+ */
+ /*----------------------------------------------------------*/
+ static void DeleteNodeEntry( uint16_t index );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Dumps out all information of all devices to stdout
+ */
+ /*----------------------------------------------------------*/
+ static void PrintAllInformations();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets the amount of connection for the current instance of MOST device.
+ * \return The amount of connections.
+ */
+ /*----------------------------------------------------------*/
+ uint16_t GetAmountOfConnections();
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets an instance of CNodeConnectionEntry by the given instance index.
+ * \param index - starting at 0 for the first instance. "GetAmountOfConnections() - 1" for the last instance.
+ * \return The requested instance, when successful. Otherwise NULL pointer.
+ */
+ /*----------------------------------------------------------*/
+ CNodeConnectionEntry *GetConnectionByIndex( uint16_t index );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Gets an instance of CNodeConnectionEntry by the given channel identifier.
+ * \param channelId - The channel identifier as specified in the XML file.
+ * \param createNewIfUnknown - TRUE, if this function shall create a new entry, when there is no existing object.
+ * \return The requested instance, when successful. Otherwise NULL pointer.
+ */
+ /*----------------------------------------------------------*/
+ CNodeConnectionEntry *GetConnectionByChannelId( uint32_t channelId, bool createNewIfUnknown );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retrieves a conflicting connection by the given parameters.#
+ * This method checks if the in and out configurations are unique for one device.
+ * \param channelId - The channel identifier as specified in the XML file.
+ * \param opposite - The other side to be connected to.
+ * \return The instance, which causes an conflict. If there is no conflict, a NULL pointer will be returned.
+ */
+ /*----------------------------------------------------------*/
+ CNodeConnectionEntry *GetConflictingConnection( uint32_t channelId, CNodeEntry *opposite );
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Delets all informations of the given channel identifier.
+ * \param channelId - The channel identifier as specified in the XML file.
+ */
+ /*----------------------------------------------------------*/
+ void DeleteConnection( uint32_t channelId );
+};
+
+#endif //NODEDATABASE_H
diff --git a/Src/Network/base/.svn/dir-prop-base b/Src/Network/base/.svn/dir-prop-base
new file mode 100644
index 0000000..c4fbe3b
--- /dev/null
+++ b/Src/Network/base/.svn/dir-prop-base
@@ -0,0 +1,14 @@
+K 16
+bugtraq:logregex
+V 67
+(?:[Bb]ugs?|[Ii]ssues?|[Rr]eports?)+\s+#(?:(?:\d+)[#,\.\s]*)+
+(\d+)
+K 15
+bugtraq:message
+V 21
+Mantis issue #%BUGID%
+K 11
+bugtraq:url
+V 33
+http://mantis/view.php?id=%BUGID%
+END
diff --git a/Src/Network/base/.svn/entries b/Src/Network/base/.svn/entries
new file mode 100644
index 0000000..eba0b2c
--- /dev/null
+++ b/Src/Network/base/.svn/entries
@@ -0,0 +1,164 @@
+10
+
+dir
+6611
+svn://kar-vm-svn01.mchp-main.com/svn/AppsTeam/Samples/iMX6+OS81118/Industrial/VideoOnDemand/tags/V3.0.4/source/Examples/NetworkManager/Server/Src/Network/base
+svn://kar-vm-svn01.mchp-main.com/svn/AppsTeam
+
+
+
+2016-03-08T10:11:00.246092Z
+5263
+tkummermehr
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+c50209ca-6af6-4c1a-9d47-4b11eae79d1c
+
+Board.c
+file
+
+
+
+
+2016-11-29T13:32:01.206172Z
+002b1b0937a1a1653ff724364be62050
+2016-03-08T10:11:00.246092Z
+5263
+tkummermehr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1685
+
+DriverConfiguration.h
+file
+
+
+
+
+2016-11-29T13:32:01.206172Z
+05273e72ca5b7af8c2f55a35fcdaa5a0
+2015-12-17T09:32:42.832988Z
+5040
+ashvetsov
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11839
+
+Board.h
+file
+
+
+
+
+2016-11-29T13:32:01.206172Z
+40cb461e8d0039b063b790d626d37f1a
+2016-03-08T10:11:00.246092Z
+5263
+tkummermehr
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1799
+
+DriverConfiguration.c
+file
+
+
+
+
+2016-11-29T13:32:01.202172Z
+b8e55c1b0e2437a8513afd32ae4f5446
+2015-12-17T09:32:42.832988Z
+5040
+ashvetsov
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+18468
+
diff --git a/Src/Network/base/.svn/prop-base/DriverConfiguration.c.svn-base b/Src/Network/base/.svn/prop-base/DriverConfiguration.c.svn-base
new file mode 100644
index 0000000..3160658
--- /dev/null
+++ b/Src/Network/base/.svn/prop-base/DriverConfiguration.c.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/Src/Network/base/.svn/prop-base/DriverConfiguration.h.svn-base b/Src/Network/base/.svn/prop-base/DriverConfiguration.h.svn-base
new file mode 100644
index 0000000..3160658
--- /dev/null
+++ b/Src/Network/base/.svn/prop-base/DriverConfiguration.h.svn-base
@@ -0,0 +1,5 @@
+K 13
+svn:mergeinfo
+V 0
+
+END
diff --git a/Src/Network/base/.svn/text-base/Board.c.svn-base b/Src/Network/base/.svn/text-base/Board.c.svn-base
new file mode 100644
index 0000000..50daf0c
--- /dev/null
+++ b/Src/Network/base/.svn/text-base/Board.c.svn-base
@@ -0,0 +1,51 @@
+/*
+ * 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 Base Board initialisation */
+/*----------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include "Board.h"
+#include "Console.h"
+
+uint32_t GetTickCount( void )
+{
+ struct timespec currentTime;
+ if (clock_gettime(CLOCK_MONOTONIC_RAW, &currentTime))
+ {
+ ConsolePrintf( PRIO_ERROR, RED"GetTickCount failed!!"RESETCOLOR"\n" );
+ return 0;
+ }
+ return ( currentTime.tv_sec * 1000 ) + ( currentTime.tv_nsec / 1000000 );
+}
+
+uint16_t GetTickCountWord()
+{
+ return ( uint16_t )( GetTickCount() & UINT16_MAX );
+}
diff --git a/Src/Network/base/.svn/text-base/Board.h.svn-base b/Src/Network/base/.svn/text-base/Board.h.svn-base
new file mode 100644
index 0000000..585a862
--- /dev/null
+++ b/Src/Network/base/.svn/text-base/Board.h.svn-base
@@ -0,0 +1,63 @@
+/*
+ * 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 component abstracts platform specific functionalities.
+ */
+/*----------------------------------------------------------*/
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+ /*----------------------------------------------------------*/
+ /*! \brief reads the ms tick counter.
+ *
+ * \return value of the ms counter.
+ */
+ /*----------------------------------------------------------*/
+ uint32_t GetTickCount( void );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief reads the ms tick counter
+ *
+ * \return value of the ms counter as word
+ */
+ /*----------------------------------------------------------*/
+ uint16_t GetTickCountWord( void );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _BOARD_H_
diff --git a/Src/Network/base/.svn/text-base/DriverConfiguration.c.svn-base b/Src/Network/base/.svn/text-base/DriverConfiguration.c.svn-base
new file mode 100644
index 0000000..7a98d25
--- /dev/null
+++ b/Src/Network/base/.svn/text-base/DriverConfiguration.c.svn-base
@@ -0,0 +1,608 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "DriverConfiguration.h"
+#include "Console.h"
+
+static bool WriteCharactersToFile( const char *pFileName, const char *pString )
+{
+ bool success = false;
+ FILE *fh = fopen( pFileName, "a" );
+ if( NULL != fh )
+ {
+ int result = fputs( pString, fh );
+ if( result >= 0 )
+ fputc( '\n', fh );
+ if( result >= 0 )
+ success = true;
+ fclose( fh );
+ }
+ if( success )
+ ConsolePrintf( PRIO_MEDIUM, "*** configured device: '%s = %s', success:%d\n", pFileName, pString, success );
+ else
+ ConsolePrintf( PRIO_ERROR, RED"DriverConfiguration.WriteCharactersToFile failed for file '%s', errno:'%s'"RESETCOLOR"\n",
+ pFileName, GetErrnoString() );
+ return success;
+}
+
+static bool WriteIntegerToFile( const char *pFileName, int intValue )
+{
+ char tempBuffer[16];
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%d", intValue );
+ return WriteCharactersToFile( pFileName, tempBuffer );
+}
+
+static bool ReadFromFile( const char *pFileName, char *pString, uint16_t bufferLen )
+{
+ bool success = false;
+ if( NULL == pString || 0 == bufferLen )
+ return success;
+ FILE *fh = fopen( pFileName, "r" );
+ if( NULL != fh )
+ {
+ success = ( NULL != fgets( pString, bufferLen, fh ) );
+ fclose( fh );
+ }
+ if( !success )
+ ConsolePrintf( PRIO_ERROR, RED"DriverConfiguration.ReadFromFile failed for file '%s', errno:'%s'"RESETCOLOR"\n",
+ pFileName, GetErrnoString() );
+ return success;
+}
+
+static bool ExistsDevice( const char *pDeviceName )
+{
+ struct stat buffer;
+ return ( stat( pDeviceName, &buffer ) == 0 );
+}
+
+static bool WaitForDevice( const char *pDeviceName )
+{
+ int timeout;
+ bool deviceExists = false;
+ for( timeout = 0; timeout < 40; timeout++ )
+ {
+ deviceExists = ExistsDevice( pDeviceName );
+ if( deviceExists )
+ {
+ break;
+ }
+ else
+ {
+ usleep( 2500 );
+ }
+ }
+ if( !deviceExists )
+ ConsolePrintf( PRIO_ERROR, RED"Waiting for device '%s' to appear, timed out"RESETCOLOR"\n",
+ pDeviceName );
+ return deviceExists;
+}
+
+static bool GetDeviceDescription( uint8_t deviceInstance, char *deviceString, uint32_t stringLen )
+{
+ bool descriptionFound = false;
+ char descriptionPath[64];
+ char descriptionValue[32];
+
+ if( NULL == deviceString )
+ return descriptionFound;
+
+ snprintf( descriptionPath, sizeof( descriptionPath ),
+ "/sys/devices/virtual/most/mostcore/devices/mdev%d/description", deviceInstance );
+
+ if( !ExistsDevice( descriptionPath ) )
+ return descriptionFound;
+
+ descriptionFound = ReadFromFile( descriptionPath, descriptionValue, sizeof( descriptionValue ) );
+ if( descriptionFound )
+ {
+ strncpy( deviceString, descriptionValue, stringLen );
+ }
+ return descriptionFound;
+}
+
+static bool ExistsDeviceWithType( uint8_t deviceInstance, const char *deviceString, uint32_t stringLen )
+{
+ bool deviceFound = false;
+ char interfacePath[64];
+ char interfaceValue[32];
+
+ if( NULL == deviceString )
+ return deviceFound;
+
+ snprintf( interfacePath, sizeof( interfacePath ), "/sys/devices/virtual/most/mostcore/devices/mdev%d/interface",
+ deviceInstance );
+
+ if( !ExistsDevice( interfacePath ) )
+ return deviceFound;
+
+ deviceFound = ReadFromFile( interfacePath, interfaceValue, sizeof( interfaceValue ) );
+ if( deviceFound )
+ {
+ deviceFound = ( 0 == strncmp( interfaceValue, deviceString, stringLen ) );
+ }
+ return deviceFound;
+}
+
+static bool GetAlsaConfiguration( uint16_t subBufferSize, uint8_t *amountOfChannels, uint8_t *bitDepth )
+{
+ if( NULL == amountOfChannels || NULL == bitDepth )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"GetAlsaConfiguration was called with invalid parameters"RESETCOLOR"\n" );
+ return false;
+ }
+ switch( subBufferSize )
+ {
+ case 2:
+ *amountOfChannels = 1;
+ *bitDepth = 16;
+ break;
+ case 4:
+ *amountOfChannels = 2;
+ *bitDepth = 16;
+ break;
+ case 6:
+ *amountOfChannels = 2;
+ *bitDepth = 24;
+ break;
+ case 8:
+ *amountOfChannels = 2;
+ *bitDepth = 32;
+ break;
+ case 12:
+ *amountOfChannels = 6;
+ *bitDepth = 16;
+ break;
+ case 18:
+ *amountOfChannels = 6;
+ *bitDepth = 24;
+ break;
+ case 16:
+ *amountOfChannels = 8;
+ *bitDepth = 16;
+ break;
+ case 24:
+ *amountOfChannels = 8;
+ *bitDepth = 24;
+ break;
+ default:
+ ConsolePrintf( PRIO_ERROR, RED"Configure ALSA device was called"\
+ " with unknown sub-buffer size: %d"RESETCOLOR"\n", subBufferSize );
+ return false;
+ }
+ return true;
+}
+
+bool ExistsUsbDeviceInstance( uint8_t deviceInstance )
+{
+ uint32_t i;
+ bool found = false;
+ uint8_t curDevInst = 0;
+ char lastDescr[64];
+ lastDescr[0] = '\0';
+ for( i = 0; i < 12; i++ )
+ {
+ uint32_t curDescrLen;
+ char curDescr[64];
+ if( !ExistsDeviceWithType( i, "usb", 3 ) )
+ continue;
+
+ if( !GetDeviceDescription( i, curDescr, sizeof( curDescr ) ) )
+ continue;
+
+ curDescrLen = strnlen( curDescr, sizeof( curDescr ) );
+ if( curDescrLen <= 2 )
+ continue;
+
+ //Cut away the last two characters, as they are different for the 3 interfaces of INIC
+ curDescrLen -= 2;
+
+ if( 0 == strncmp( curDescr, lastDescr, curDescrLen ) )
+ continue;
+
+ strncpy( lastDescr, curDescr, curDescrLen );
+ lastDescr[curDescrLen] = '\0';
+
+ if( curDevInst++ != deviceInstance )
+ continue;
+
+ found = true;
+ break;
+ }
+ return found;
+}
+
+bool ExistsMlbDeviceInstance( uint8_t deviceInstance )
+{
+ return ExistsDeviceWithType( deviceInstance, "mlb", 3 );
+}
+
+bool ExistsI2CDeviceInstance( uint8_t deviceInstance )
+{
+ return ExistsDeviceWithType( deviceInstance, "i2c", 3 );
+}
+
+bool GetUsbDeviceNames( uint8_t deviceInstance, uint8_t endpointAddress, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength )
+{
+ uint32_t i;
+ bool systemFound = false;
+ uint8_t curDevInst = 0;
+ char lastDescr[64];
+ lastDescr[0] = '\0';
+ char endpointBuffer[16];
+ char systemSourceDir[64];
+ DIR *d;
+ struct dirent *dir;
+
+ if( NULL == deviceName || NULL == systemName || NULL == linkName )
+ return false;
+
+ deviceName[0] = '\0';
+ systemName[0] = '\0';
+
+ for( i = 0; !systemFound && i < 12; i++ )
+ {
+ uint32_t curDescrLen;
+ char curDescr[64];
+ if( !ExistsDeviceWithType( i, "usb", 3 ) )
+ continue;
+
+ if( !GetDeviceDescription( i, curDescr, sizeof( curDescr ) ) )
+ continue;
+
+ curDescrLen = strnlen( curDescr, sizeof( curDescr ) );
+ if( curDescrLen <= 2 )
+ continue;
+
+ //Cut away the last two characters, as they are different for the 3 interfaces of INIC
+ curDescrLen -= 2;
+
+ if( ( '\0' != lastDescr[0] )
+ && ( 0 != strncmp( curDescr, lastDescr, curDescrLen ) ) )
+ {
+ ++curDevInst;
+ }
+
+ strncpy( lastDescr, curDescr, curDescrLen );
+ lastDescr[curDescrLen] = '\0';
+
+ if( curDevInst < deviceInstance )
+ continue;
+ else if( curDevInst > deviceInstance )
+ break;
+
+ snprintf( endpointBuffer, sizeof( endpointBuffer ), "ep%02x", endpointAddress );
+ snprintf( systemSourceDir, sizeof( systemSourceDir ), "/sys/devices/virtual/most/mostcore/devices/mdev%d", i );
+ d = opendir( systemSourceDir );
+ if( d )
+ {
+ while( ( dir = readdir( d ) ) != NULL )
+ {
+ if( strstr( dir->d_name, endpointBuffer ) )
+ {
+ snprintf( systemName, systemNameLength, "%s/%s", systemSourceDir, dir->d_name );
+ snprintf( deviceName, deviceNameLength, "/dev/mdev%d-%s", deviceInstance, dir->d_name );
+ snprintf( linkName, linkNameLength, "mdev%d:%s:mdev%d-%s", i, dir->d_name, deviceInstance,
+ dir->d_name );
+ systemFound = true;
+ break;
+ }
+ }
+ closedir( d );
+ }
+ }
+ return systemFound;
+}
+
+bool GetMlbDeviceNames( uint8_t deviceInstance, uint8_t mlbChannelAddress, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength )
+{
+ bool systemFound = false;
+ char channelBuffer[16];
+ char systemSourceDir[64];
+ DIR *d;
+ struct dirent *dir;
+
+ if( NULL == deviceName || NULL == systemName || NULL == linkName )
+ return false;
+
+ deviceName[0] = '\0';
+ systemName[0] = '\0';
+
+ snprintf( channelBuffer, sizeof( channelBuffer ), "ca%d", mlbChannelAddress );
+ snprintf( systemSourceDir, sizeof( systemSourceDir ), "/sys/devices/virtual/most/mostcore/devices/mdev%d",
+ deviceInstance );
+ d = opendir( systemSourceDir );
+ if( d )
+ {
+ while( ( dir = readdir( d ) ) != NULL )
+ {
+ if( strstr( dir->d_name, channelBuffer ) )
+ {
+ snprintf( systemName, systemNameLength, "%s/%s", systemSourceDir, dir->d_name );
+ snprintf( deviceName, deviceNameLength, "/dev/mdev%d-%s", deviceInstance, dir->d_name );
+ snprintf( linkName, linkNameLength, "mdev%d:%s:mdev%d-%s", deviceInstance, dir->d_name, deviceInstance,
+ dir->d_name );
+ systemFound = true;
+ break;
+ }
+ }
+ closedir( d );
+ }
+ return systemFound;
+}
+
+bool GetI2CDeviceNames( uint8_t deviceInstance, bool isTx, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength )
+{
+ bool systemFound = false;
+ char systemSourceDir[64];
+ DIR *d;
+ struct dirent *dir;
+
+ if( NULL == deviceName || NULL == systemName || NULL == linkName )
+ return false;
+
+ deviceName[0] = '\0';
+ systemName[0] = '\0';
+
+ snprintf( systemSourceDir, sizeof( systemSourceDir ), "/sys/devices/virtual/most/mostcore/devices/mdev%d",
+ deviceInstance );
+ d = opendir( systemSourceDir );
+ if( d )
+ {
+ while( ( dir = readdir( d ) ) != NULL )
+ {
+ if( strstr( dir->d_name, ( isTx ? "tx" : "rx" ) ) )
+ {
+ snprintf( systemName, systemNameLength, "%s/%s", systemSourceDir, dir->d_name );
+ snprintf( deviceName, deviceNameLength, "/dev/mdev%d-%s", deviceInstance, dir->d_name );
+ snprintf( linkName, linkNameLength, "mdev%d:%s:mdev%d-%s", deviceInstance, dir->d_name, deviceInstance,
+ dir->d_name );
+ systemFound = true;
+ break;
+ }
+ }
+ closedir( d );
+ }
+ return systemFound;
+}
+
+bool CloseMostChannel( const char *device )
+{
+ return true;
+}
+
+bool ConfigureMostChannel( const char *device, EPDataType_t mostType, EPDirection_t direction, uint32_t numBuf,
+ uint32_t bufSize )
+{
+ static const char *controlType = "control";
+ static const char *asyncType = "async";
+ static const char *syncType = "sync";
+ static const char *isocType = "isoc_avp";
+ static const char *rxDirection = "dir_rx";
+ static const char *txDirection = "dir_tx";
+ bool success = true;
+ char tempBuffer[128];
+ const char *typeString = NULL;
+ const char *directionString = NULL;
+
+ switch( mostType )
+ {
+ case EP_Control:
+ typeString = controlType;
+ break;
+ case EP_Asynchron:
+ typeString = asyncType;
+ break;
+ case EP_Synchron:
+ typeString = syncType;
+ break;
+ case EP_Isochron:
+ typeString = isocType;
+ break;
+ default:
+ return false;
+ }
+
+ switch( direction )
+ {
+ case EPDIR_IN:
+ directionString = txDirection;
+ break;
+ case EPDIR_OUT:
+ directionString = rxDirection;
+ break;
+ default:
+ return false;
+ }
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_datatype", device ); /// Setting data type
+ success = WriteCharactersToFile( tempBuffer, typeString );
+ if( success )
+ {
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_direction", device ); /// Setting direction
+ success = WriteCharactersToFile( tempBuffer, directionString );
+ }
+ if( success )
+ {
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_number_of_buffers", device ); /// Setting amount of buffers
+ success = WriteIntegerToFile( tempBuffer, numBuf );
+ }
+ if( success )
+ {
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_buffer_size", device ); /// Setting amount of buffers
+ success = WriteIntegerToFile( tempBuffer, bufSize );
+ }
+ return success;
+}
+
+bool ConfigureIsocChannel( const char *device, uint32_t subbufferSize, uint32_t packetsPerTransaction )
+{
+ char tempBuffer[128];
+ bool success;
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_subbuffer_size", device ); /// Setting the subbuffer size in bytes
+ success = WriteIntegerToFile( tempBuffer, subbufferSize );
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_packets_per_xact", device ); /// Setting the packets per transaction
+ success = WriteIntegerToFile( tempBuffer, ( packetsPerTransaction & 0xFF ) );
+ return success;
+}
+
+bool ConfigureSyncChannel( const char *device, uint32_t syncBlockWidth, uint32_t amounOfSyncFrames )
+{
+ char tempBuffer[128];
+ bool success;
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_packets_per_xact", device ); /// Setting the amount of frames in one USB frame
+ success = WriteIntegerToFile( tempBuffer, amounOfSyncFrames );
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_subbuffer_size", device ); /// Setting the blockwidth of a single frame
+ success = WriteIntegerToFile( tempBuffer, syncBlockWidth );
+ return success;
+}
+
+bool LinkToCharacterDevice( const char *linkName, const char *deviceName )
+{
+ bool success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/cdev/add_link", linkName );
+ if( success )
+ {
+ success = WaitForDevice( deviceName );
+ }
+ if( success )
+ {
+ chmod( deviceName, ( S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ) );
+ }
+ return success;
+}
+
+bool LinkToAudioDevice( const char *linkName, uint16_t subBufferSize )
+{
+ char tempBuffer[128];
+ uint8_t amountOfChannels;
+ uint8_t bitDepth;
+ if( !GetAlsaConfiguration( subBufferSize, &amountOfChannels, &bitDepth ) )
+ return false;
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s.%dx%d", linkName, amountOfChannels, bitDepth ); /// Add the channel information behind the Link Name
+
+ //Be compatible to all versions of MOST Linux Driver. The name was changed of Sound AIM.
+ bool success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/sound/add_link", tempBuffer );
+ if( !success )
+ success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/audio/add_link", tempBuffer );
+ return success;
+}
+
+bool LinkToVideoForLinuxDevice( const char *linkName )
+{
+ bool success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/v4l/add_link", linkName );
+ return success;
+}
+
+const char *GetErrnoString()
+{
+ switch( errno )
+ {
+ case 0:
+ return "Nothing stored in errno";
+ case 1:
+ return "Operation not permitted";
+ case 2:
+ return "No such file or directory";
+ case 3:
+ return "No such process";
+ case 4:
+ return "Interrupted system call";
+ case 5:
+ return "I/O error";
+ case 6:
+ return "No such device or address";
+ case 7:
+ return "Argument list too long";
+ case 8:
+ return "Exec format error";
+ case 9:
+ return "Bad file number";
+ case 10:
+ return "No child processes";
+ case 11:
+ return "Try again";
+ case 12:
+ return "Out of memory";
+ case 13:
+ return "Permission denied";
+ case 14:
+ return "Bad address";
+ case 15:
+ return "Block device required";
+ case 16:
+ return "Device or resource busy";
+ case 17:
+ return "File exists";
+ case 18:
+ return "Cross-device link";
+ case 19:
+ return "No such device";
+ case 20:
+ return "Not a directory";
+ case 21:
+ return "Is a directory";
+ case 22:
+ return "Invalid argument";
+ case 23:
+ return "File table overflow";
+ case 24:
+ return "Too many open files";
+ case 25:
+ return "Not a typewriter";
+ case 26:
+ return "Text file busy";
+ case 27:
+ return "File too large";
+ case 28:
+ return "No space left on device";
+ case 29:
+ return "Illegal seek";
+ case 30:
+ return "Read-only file system";
+ case 31:
+ return "Too many links";
+ case 32:
+ return "Broken pipe";
+ case 33:
+ return "Math argument out of domain of func";
+ case 34:
+ return "Math result not representable";
+ default:
+ break;
+ }
+ return "Unknown";
+}
diff --git a/Src/Network/base/.svn/text-base/DriverConfiguration.h.svn-base b/Src/Network/base/.svn/text-base/DriverConfiguration.h.svn-base
new file mode 100644
index 0000000..b2fd44a
--- /dev/null
+++ b/Src/Network/base/.svn/text-base/DriverConfiguration.h.svn-base
@@ -0,0 +1,239 @@
+/*
+ * 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 component provides helper tools to deal with USB endpoints.
+ */
+/*----------------------------------------------------------*/
+#ifndef DRIVERCONFIGURATION_H
+#define DRIVERCONFIGURATION_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /*----------------------------------------------------------*/
+ /*! \brief Checks if the given USB device instance exists.
+ *
+ * \param deviceInstance - The device instance of the USB INIC, starting at 0 for the first instance.
+ *
+ * \return true: Device exists.
+ * \return false: Device does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool ExistsUsbDeviceInstance( uint8_t deviceInstance );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Checks if the given MLB device instance exists.
+ *
+ * \param deviceInstance - The device instance of the MLB INIC, starting at 0 for the first instance.
+ *
+ * \return true: Device exists.
+ * \return false: Device does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool ExistsMlbDeviceInstance( uint8_t deviceInstance );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Checks if the given I2C device instance exists.
+ *
+ * \param deviceInstance - The device instance of the I2C INIC, starting at 0 for the first instance.
+ *
+ * \return true: Device exists.
+ * \return false: Device does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool ExistsI2CDeviceInstance( uint8_t deviceInstance );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retreives the Linux character device names for the given USB device instance and the endpoint address.
+ *
+ * \note If the given buffer is too small to hold the whole path, the string is truncated and not useable!
+ *
+ * \param deviceInstance - The device instance of the USB INIC, starting at 0 for the first instance.
+ * \param endpointAddress - The USB endpoint address, RX endpoints starting with upper bit set (0x8X).
+ * \param deviceName - [in,out] Given buffer will be filled with device name (starting with /dev/).
+ * \param deviceNameLength - The length of the given deviceName buffer in bytes.
+ * \param systemName - [in,out] Given buffer will be filled with system name (starting with /sys/).
+ * \param systemNameLength - The length of the given systemName buffer in bytes.
+ * \param linkName - [in,out] Given buffer will be filled with the string needed to register this device to an AIM
+ * \param linkNameLength - The length of the given linkName buffer in bytes.
+ *
+ * \return true: Operation was successful.
+ * \return false: Operation failed, device or endpoint does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool GetUsbDeviceNames( uint8_t deviceInstance, uint8_t endpointAddress, char *deviceName,
+ uint16_t deviceNameLength, char *systemName, uint16_t systemNameLength, char *linkName,
+ uint16_t linkNameLength );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retreives the Linux character device names for the given MLB device instance and the endpoint address.
+ *
+ * \note If the given buffer is too small to hold the whole path, the string is truncated and not useable!
+ *
+ * \param deviceInstance - The device instance of the USB INIC, starting at 0 for the first instance.
+ * \param mlbChannelAddress - The MLB channel address
+ * \param deviceName - [in,out] Given buffer will be filled with device name (starting with /dev/).
+ * \param deviceNameLength - The length of the given deviceName buffer in bytes.
+ * \param systemName - [in,out] Given buffer will be filled with system name (starting with /sys/).
+ * \param systemNameLength - The length of the given systemName buffer in bytes.
+ * \param linkName - [in,out] Given buffer will be filled with the string needed to register this device to an AIM
+ * \param linkNameLength - The length of the given linkName buffer in bytes.
+ *
+ * \return true: Operation was successful.
+ * \return false: Operation failed, device or endpoint does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool GetMlbDeviceNames( uint8_t deviceInstance, uint8_t mlbChannelAddress, char *deviceName,
+ uint16_t deviceNameLength, char *systemName, uint16_t systemNameLength, char *linkName,
+ uint16_t linkNameLength );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retreives the Linux character device names for the given I2C device instance and the endpoint address.
+ *
+ * \note If the given buffer is too small to hold the whole path, the string is truncated and not useable!
+ *
+ * \param deviceInstance - The device instance of the I2C INIC, starting at 0 for the first instance.
+ * \param isTx - true, if the names for transmission path should be retrieved, otherwise for the reception path.
+ * \param deviceName - [in,out] Given buffer will be filled with device name (starting with /dev/).
+ * \param deviceNameLength - The length of the given deviceName buffer in bytes.
+ * \param systemName - [in,out] Given buffer will be filled with system name (starting with /sys/).
+ * \param systemNameLength - The length of the given systemName buffer in bytes.
+ * \param linkName - [in,out] Given buffer will be filled with the string needed to register this device to an AIM
+ * \param linkNameLength - The length of the given linkName buffer in bytes.
+ *
+ * \return true: Operation was successful.
+ * \return false: Operation failed, device or endpoint does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool GetI2CDeviceNames( uint8_t deviceInstance, bool isTx, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Closes the MOST channel.
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool CloseMostChannel( const char *device );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures the MOST channel.
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ * \param mostType - The MOST data type (control, asynchron, synchron, isochron).
+ * \param direction - The direction of the stream (directionRX, directionTX).
+ * \param numBuf - The amount of buffers.
+ * \param bufSize - The size of each buffer in bytes.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureMostChannel( const char *device, EPDataType_t mostType, EPDirection_t direction, uint32_t numBuf,
+ uint32_t bufSize );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures the isochronous channel of a device.
+ * \note This function has to be called before ConfigureMostChannel!
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ * \param subbufferSize - The amount of bytes for a single subbuffer (eg. 188 or 196 bytes).
+ * \param packetsPerTransaction - The amount of ischronous packets per transaction.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureIsocChannel( const char *device, uint32_t subbufferSize, uint32_t packetsPerTransaction );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures the Synchronous channel of a device.
+ * \note This function has to be called before ConfigureMostChannel!
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ * \param syncBlockWidth - The bandwidth of a single synchronous frame. Ignored if not sync channel.
+ * \param amounOfSyncFrames - The amount of synchronous frames per USB packet. Ignored if not sync channel.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureSyncChannel( const char *device, uint32_t syncBlockWidth, uint32_t amounOfSyncFrames );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a character device for the given device's link name.
+ *
+ * \param linkName - [in] Link name, which is needed to register this device to an AIM.
+ * \param deviceName - [in,out] Device name (starting with /dev/).
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool LinkToCharacterDevice( const char *linkName, const char *deviceName );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a audio device (ALSA) for the given device's link name.
+ *
+ * \param linkName - [in] Link name, which is needed to register this device to an AIM.
+ * \param subBufferSize - [in] The amount of bytes for all channels of this connection on the MOST.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool LinkToAudioDevice( const char *linkName, uint16_t subBufferSize );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a Video for Linux device (V4L) for the given device's link name.
+ *
+ * \param linkName - [in] Link name, which is needed to register this device to an AIM.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool LinkToVideoForLinuxDevice( const char *linkName );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Parsed the global errno variable and generate a human readable error description out of it.
+ *
+ * \return Zero terminated error description string.
+ */
+ /*----------------------------------------------------------*/
+ const char *GetErrnoString();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //DRIVERCONFIGURATION_H
diff --git a/Src/Network/base/Board.c b/Src/Network/base/Board.c
new file mode 100644
index 0000000..50daf0c
--- /dev/null
+++ b/Src/Network/base/Board.c
@@ -0,0 +1,51 @@
+/*
+ * 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 Base Board initialisation */
+/*----------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include "Board.h"
+#include "Console.h"
+
+uint32_t GetTickCount( void )
+{
+ struct timespec currentTime;
+ if (clock_gettime(CLOCK_MONOTONIC_RAW, &currentTime))
+ {
+ ConsolePrintf( PRIO_ERROR, RED"GetTickCount failed!!"RESETCOLOR"\n" );
+ return 0;
+ }
+ return ( currentTime.tv_sec * 1000 ) + ( currentTime.tv_nsec / 1000000 );
+}
+
+uint16_t GetTickCountWord()
+{
+ return ( uint16_t )( GetTickCount() & UINT16_MAX );
+}
diff --git a/Src/Network/base/Board.h b/Src/Network/base/Board.h
new file mode 100644
index 0000000..585a862
--- /dev/null
+++ b/Src/Network/base/Board.h
@@ -0,0 +1,63 @@
+/*
+ * 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 component abstracts platform specific functionalities.
+ */
+/*----------------------------------------------------------*/
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+ /*----------------------------------------------------------*/
+ /*! \brief reads the ms tick counter.
+ *
+ * \return value of the ms counter.
+ */
+ /*----------------------------------------------------------*/
+ uint32_t GetTickCount( void );
+
+
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief reads the ms tick counter
+ *
+ * \return value of the ms counter as word
+ */
+ /*----------------------------------------------------------*/
+ uint16_t GetTickCountWord( void );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _BOARD_H_
diff --git a/Src/Network/base/DriverConfiguration.c b/Src/Network/base/DriverConfiguration.c
new file mode 100644
index 0000000..7a98d25
--- /dev/null
+++ b/Src/Network/base/DriverConfiguration.c
@@ -0,0 +1,608 @@
+/*
+ * Video On Demand Samples
+ *
+ * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You may also obtain this software under a propriety license from Microchip.
+ * Please contact Microchip for further information.
+ *
+ */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "DriverConfiguration.h"
+#include "Console.h"
+
+static bool WriteCharactersToFile( const char *pFileName, const char *pString )
+{
+ bool success = false;
+ FILE *fh = fopen( pFileName, "a" );
+ if( NULL != fh )
+ {
+ int result = fputs( pString, fh );
+ if( result >= 0 )
+ fputc( '\n', fh );
+ if( result >= 0 )
+ success = true;
+ fclose( fh );
+ }
+ if( success )
+ ConsolePrintf( PRIO_MEDIUM, "*** configured device: '%s = %s', success:%d\n", pFileName, pString, success );
+ else
+ ConsolePrintf( PRIO_ERROR, RED"DriverConfiguration.WriteCharactersToFile failed for file '%s', errno:'%s'"RESETCOLOR"\n",
+ pFileName, GetErrnoString() );
+ return success;
+}
+
+static bool WriteIntegerToFile( const char *pFileName, int intValue )
+{
+ char tempBuffer[16];
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%d", intValue );
+ return WriteCharactersToFile( pFileName, tempBuffer );
+}
+
+static bool ReadFromFile( const char *pFileName, char *pString, uint16_t bufferLen )
+{
+ bool success = false;
+ if( NULL == pString || 0 == bufferLen )
+ return success;
+ FILE *fh = fopen( pFileName, "r" );
+ if( NULL != fh )
+ {
+ success = ( NULL != fgets( pString, bufferLen, fh ) );
+ fclose( fh );
+ }
+ if( !success )
+ ConsolePrintf( PRIO_ERROR, RED"DriverConfiguration.ReadFromFile failed for file '%s', errno:'%s'"RESETCOLOR"\n",
+ pFileName, GetErrnoString() );
+ return success;
+}
+
+static bool ExistsDevice( const char *pDeviceName )
+{
+ struct stat buffer;
+ return ( stat( pDeviceName, &buffer ) == 0 );
+}
+
+static bool WaitForDevice( const char *pDeviceName )
+{
+ int timeout;
+ bool deviceExists = false;
+ for( timeout = 0; timeout < 40; timeout++ )
+ {
+ deviceExists = ExistsDevice( pDeviceName );
+ if( deviceExists )
+ {
+ break;
+ }
+ else
+ {
+ usleep( 2500 );
+ }
+ }
+ if( !deviceExists )
+ ConsolePrintf( PRIO_ERROR, RED"Waiting for device '%s' to appear, timed out"RESETCOLOR"\n",
+ pDeviceName );
+ return deviceExists;
+}
+
+static bool GetDeviceDescription( uint8_t deviceInstance, char *deviceString, uint32_t stringLen )
+{
+ bool descriptionFound = false;
+ char descriptionPath[64];
+ char descriptionValue[32];
+
+ if( NULL == deviceString )
+ return descriptionFound;
+
+ snprintf( descriptionPath, sizeof( descriptionPath ),
+ "/sys/devices/virtual/most/mostcore/devices/mdev%d/description", deviceInstance );
+
+ if( !ExistsDevice( descriptionPath ) )
+ return descriptionFound;
+
+ descriptionFound = ReadFromFile( descriptionPath, descriptionValue, sizeof( descriptionValue ) );
+ if( descriptionFound )
+ {
+ strncpy( deviceString, descriptionValue, stringLen );
+ }
+ return descriptionFound;
+}
+
+static bool ExistsDeviceWithType( uint8_t deviceInstance, const char *deviceString, uint32_t stringLen )
+{
+ bool deviceFound = false;
+ char interfacePath[64];
+ char interfaceValue[32];
+
+ if( NULL == deviceString )
+ return deviceFound;
+
+ snprintf( interfacePath, sizeof( interfacePath ), "/sys/devices/virtual/most/mostcore/devices/mdev%d/interface",
+ deviceInstance );
+
+ if( !ExistsDevice( interfacePath ) )
+ return deviceFound;
+
+ deviceFound = ReadFromFile( interfacePath, interfaceValue, sizeof( interfaceValue ) );
+ if( deviceFound )
+ {
+ deviceFound = ( 0 == strncmp( interfaceValue, deviceString, stringLen ) );
+ }
+ return deviceFound;
+}
+
+static bool GetAlsaConfiguration( uint16_t subBufferSize, uint8_t *amountOfChannels, uint8_t *bitDepth )
+{
+ if( NULL == amountOfChannels || NULL == bitDepth )
+ {
+ ConsolePrintf( PRIO_ERROR, RED"GetAlsaConfiguration was called with invalid parameters"RESETCOLOR"\n" );
+ return false;
+ }
+ switch( subBufferSize )
+ {
+ case 2:
+ *amountOfChannels = 1;
+ *bitDepth = 16;
+ break;
+ case 4:
+ *amountOfChannels = 2;
+ *bitDepth = 16;
+ break;
+ case 6:
+ *amountOfChannels = 2;
+ *bitDepth = 24;
+ break;
+ case 8:
+ *amountOfChannels = 2;
+ *bitDepth = 32;
+ break;
+ case 12:
+ *amountOfChannels = 6;
+ *bitDepth = 16;
+ break;
+ case 18:
+ *amountOfChannels = 6;
+ *bitDepth = 24;
+ break;
+ case 16:
+ *amountOfChannels = 8;
+ *bitDepth = 16;
+ break;
+ case 24:
+ *amountOfChannels = 8;
+ *bitDepth = 24;
+ break;
+ default:
+ ConsolePrintf( PRIO_ERROR, RED"Configure ALSA device was called"\
+ " with unknown sub-buffer size: %d"RESETCOLOR"\n", subBufferSize );
+ return false;
+ }
+ return true;
+}
+
+bool ExistsUsbDeviceInstance( uint8_t deviceInstance )
+{
+ uint32_t i;
+ bool found = false;
+ uint8_t curDevInst = 0;
+ char lastDescr[64];
+ lastDescr[0] = '\0';
+ for( i = 0; i < 12; i++ )
+ {
+ uint32_t curDescrLen;
+ char curDescr[64];
+ if( !ExistsDeviceWithType( i, "usb", 3 ) )
+ continue;
+
+ if( !GetDeviceDescription( i, curDescr, sizeof( curDescr ) ) )
+ continue;
+
+ curDescrLen = strnlen( curDescr, sizeof( curDescr ) );
+ if( curDescrLen <= 2 )
+ continue;
+
+ //Cut away the last two characters, as they are different for the 3 interfaces of INIC
+ curDescrLen -= 2;
+
+ if( 0 == strncmp( curDescr, lastDescr, curDescrLen ) )
+ continue;
+
+ strncpy( lastDescr, curDescr, curDescrLen );
+ lastDescr[curDescrLen] = '\0';
+
+ if( curDevInst++ != deviceInstance )
+ continue;
+
+ found = true;
+ break;
+ }
+ return found;
+}
+
+bool ExistsMlbDeviceInstance( uint8_t deviceInstance )
+{
+ return ExistsDeviceWithType( deviceInstance, "mlb", 3 );
+}
+
+bool ExistsI2CDeviceInstance( uint8_t deviceInstance )
+{
+ return ExistsDeviceWithType( deviceInstance, "i2c", 3 );
+}
+
+bool GetUsbDeviceNames( uint8_t deviceInstance, uint8_t endpointAddress, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength )
+{
+ uint32_t i;
+ bool systemFound = false;
+ uint8_t curDevInst = 0;
+ char lastDescr[64];
+ lastDescr[0] = '\0';
+ char endpointBuffer[16];
+ char systemSourceDir[64];
+ DIR *d;
+ struct dirent *dir;
+
+ if( NULL == deviceName || NULL == systemName || NULL == linkName )
+ return false;
+
+ deviceName[0] = '\0';
+ systemName[0] = '\0';
+
+ for( i = 0; !systemFound && i < 12; i++ )
+ {
+ uint32_t curDescrLen;
+ char curDescr[64];
+ if( !ExistsDeviceWithType( i, "usb", 3 ) )
+ continue;
+
+ if( !GetDeviceDescription( i, curDescr, sizeof( curDescr ) ) )
+ continue;
+
+ curDescrLen = strnlen( curDescr, sizeof( curDescr ) );
+ if( curDescrLen <= 2 )
+ continue;
+
+ //Cut away the last two characters, as they are different for the 3 interfaces of INIC
+ curDescrLen -= 2;
+
+ if( ( '\0' != lastDescr[0] )
+ && ( 0 != strncmp( curDescr, lastDescr, curDescrLen ) ) )
+ {
+ ++curDevInst;
+ }
+
+ strncpy( lastDescr, curDescr, curDescrLen );
+ lastDescr[curDescrLen] = '\0';
+
+ if( curDevInst < deviceInstance )
+ continue;
+ else if( curDevInst > deviceInstance )
+ break;
+
+ snprintf( endpointBuffer, sizeof( endpointBuffer ), "ep%02x", endpointAddress );
+ snprintf( systemSourceDir, sizeof( systemSourceDir ), "/sys/devices/virtual/most/mostcore/devices/mdev%d", i );
+ d = opendir( systemSourceDir );
+ if( d )
+ {
+ while( ( dir = readdir( d ) ) != NULL )
+ {
+ if( strstr( dir->d_name, endpointBuffer ) )
+ {
+ snprintf( systemName, systemNameLength, "%s/%s", systemSourceDir, dir->d_name );
+ snprintf( deviceName, deviceNameLength, "/dev/mdev%d-%s", deviceInstance, dir->d_name );
+ snprintf( linkName, linkNameLength, "mdev%d:%s:mdev%d-%s", i, dir->d_name, deviceInstance,
+ dir->d_name );
+ systemFound = true;
+ break;
+ }
+ }
+ closedir( d );
+ }
+ }
+ return systemFound;
+}
+
+bool GetMlbDeviceNames( uint8_t deviceInstance, uint8_t mlbChannelAddress, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength )
+{
+ bool systemFound = false;
+ char channelBuffer[16];
+ char systemSourceDir[64];
+ DIR *d;
+ struct dirent *dir;
+
+ if( NULL == deviceName || NULL == systemName || NULL == linkName )
+ return false;
+
+ deviceName[0] = '\0';
+ systemName[0] = '\0';
+
+ snprintf( channelBuffer, sizeof( channelBuffer ), "ca%d", mlbChannelAddress );
+ snprintf( systemSourceDir, sizeof( systemSourceDir ), "/sys/devices/virtual/most/mostcore/devices/mdev%d",
+ deviceInstance );
+ d = opendir( systemSourceDir );
+ if( d )
+ {
+ while( ( dir = readdir( d ) ) != NULL )
+ {
+ if( strstr( dir->d_name, channelBuffer ) )
+ {
+ snprintf( systemName, systemNameLength, "%s/%s", systemSourceDir, dir->d_name );
+ snprintf( deviceName, deviceNameLength, "/dev/mdev%d-%s", deviceInstance, dir->d_name );
+ snprintf( linkName, linkNameLength, "mdev%d:%s:mdev%d-%s", deviceInstance, dir->d_name, deviceInstance,
+ dir->d_name );
+ systemFound = true;
+ break;
+ }
+ }
+ closedir( d );
+ }
+ return systemFound;
+}
+
+bool GetI2CDeviceNames( uint8_t deviceInstance, bool isTx, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength )
+{
+ bool systemFound = false;
+ char systemSourceDir[64];
+ DIR *d;
+ struct dirent *dir;
+
+ if( NULL == deviceName || NULL == systemName || NULL == linkName )
+ return false;
+
+ deviceName[0] = '\0';
+ systemName[0] = '\0';
+
+ snprintf( systemSourceDir, sizeof( systemSourceDir ), "/sys/devices/virtual/most/mostcore/devices/mdev%d",
+ deviceInstance );
+ d = opendir( systemSourceDir );
+ if( d )
+ {
+ while( ( dir = readdir( d ) ) != NULL )
+ {
+ if( strstr( dir->d_name, ( isTx ? "tx" : "rx" ) ) )
+ {
+ snprintf( systemName, systemNameLength, "%s/%s", systemSourceDir, dir->d_name );
+ snprintf( deviceName, deviceNameLength, "/dev/mdev%d-%s", deviceInstance, dir->d_name );
+ snprintf( linkName, linkNameLength, "mdev%d:%s:mdev%d-%s", deviceInstance, dir->d_name, deviceInstance,
+ dir->d_name );
+ systemFound = true;
+ break;
+ }
+ }
+ closedir( d );
+ }
+ return systemFound;
+}
+
+bool CloseMostChannel( const char *device )
+{
+ return true;
+}
+
+bool ConfigureMostChannel( const char *device, EPDataType_t mostType, EPDirection_t direction, uint32_t numBuf,
+ uint32_t bufSize )
+{
+ static const char *controlType = "control";
+ static const char *asyncType = "async";
+ static const char *syncType = "sync";
+ static const char *isocType = "isoc_avp";
+ static const char *rxDirection = "dir_rx";
+ static const char *txDirection = "dir_tx";
+ bool success = true;
+ char tempBuffer[128];
+ const char *typeString = NULL;
+ const char *directionString = NULL;
+
+ switch( mostType )
+ {
+ case EP_Control:
+ typeString = controlType;
+ break;
+ case EP_Asynchron:
+ typeString = asyncType;
+ break;
+ case EP_Synchron:
+ typeString = syncType;
+ break;
+ case EP_Isochron:
+ typeString = isocType;
+ break;
+ default:
+ return false;
+ }
+
+ switch( direction )
+ {
+ case EPDIR_IN:
+ directionString = txDirection;
+ break;
+ case EPDIR_OUT:
+ directionString = rxDirection;
+ break;
+ default:
+ return false;
+ }
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_datatype", device ); /// Setting data type
+ success = WriteCharactersToFile( tempBuffer, typeString );
+ if( success )
+ {
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_direction", device ); /// Setting direction
+ success = WriteCharactersToFile( tempBuffer, directionString );
+ }
+ if( success )
+ {
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_number_of_buffers", device ); /// Setting amount of buffers
+ success = WriteIntegerToFile( tempBuffer, numBuf );
+ }
+ if( success )
+ {
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_buffer_size", device ); /// Setting amount of buffers
+ success = WriteIntegerToFile( tempBuffer, bufSize );
+ }
+ return success;
+}
+
+bool ConfigureIsocChannel( const char *device, uint32_t subbufferSize, uint32_t packetsPerTransaction )
+{
+ char tempBuffer[128];
+ bool success;
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_subbuffer_size", device ); /// Setting the subbuffer size in bytes
+ success = WriteIntegerToFile( tempBuffer, subbufferSize );
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_packets_per_xact", device ); /// Setting the packets per transaction
+ success = WriteIntegerToFile( tempBuffer, ( packetsPerTransaction & 0xFF ) );
+ return success;
+}
+
+bool ConfigureSyncChannel( const char *device, uint32_t syncBlockWidth, uint32_t amounOfSyncFrames )
+{
+ char tempBuffer[128];
+ bool success;
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_packets_per_xact", device ); /// Setting the amount of frames in one USB frame
+ success = WriteIntegerToFile( tempBuffer, amounOfSyncFrames );
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s/set_subbuffer_size", device ); /// Setting the blockwidth of a single frame
+ success = WriteIntegerToFile( tempBuffer, syncBlockWidth );
+ return success;
+}
+
+bool LinkToCharacterDevice( const char *linkName, const char *deviceName )
+{
+ bool success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/cdev/add_link", linkName );
+ if( success )
+ {
+ success = WaitForDevice( deviceName );
+ }
+ if( success )
+ {
+ chmod( deviceName, ( S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ) );
+ }
+ return success;
+}
+
+bool LinkToAudioDevice( const char *linkName, uint16_t subBufferSize )
+{
+ char tempBuffer[128];
+ uint8_t amountOfChannels;
+ uint8_t bitDepth;
+ if( !GetAlsaConfiguration( subBufferSize, &amountOfChannels, &bitDepth ) )
+ return false;
+
+ snprintf( tempBuffer, sizeof( tempBuffer ), "%s.%dx%d", linkName, amountOfChannels, bitDepth ); /// Add the channel information behind the Link Name
+
+ //Be compatible to all versions of MOST Linux Driver. The name was changed of Sound AIM.
+ bool success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/sound/add_link", tempBuffer );
+ if( !success )
+ success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/audio/add_link", tempBuffer );
+ return success;
+}
+
+bool LinkToVideoForLinuxDevice( const char *linkName )
+{
+ bool success =
+ WriteCharactersToFile( "/sys/devices/virtual/most/mostcore/aims/v4l/add_link", linkName );
+ return success;
+}
+
+const char *GetErrnoString()
+{
+ switch( errno )
+ {
+ case 0:
+ return "Nothing stored in errno";
+ case 1:
+ return "Operation not permitted";
+ case 2:
+ return "No such file or directory";
+ case 3:
+ return "No such process";
+ case 4:
+ return "Interrupted system call";
+ case 5:
+ return "I/O error";
+ case 6:
+ return "No such device or address";
+ case 7:
+ return "Argument list too long";
+ case 8:
+ return "Exec format error";
+ case 9:
+ return "Bad file number";
+ case 10:
+ return "No child processes";
+ case 11:
+ return "Try again";
+ case 12:
+ return "Out of memory";
+ case 13:
+ return "Permission denied";
+ case 14:
+ return "Bad address";
+ case 15:
+ return "Block device required";
+ case 16:
+ return "Device or resource busy";
+ case 17:
+ return "File exists";
+ case 18:
+ return "Cross-device link";
+ case 19:
+ return "No such device";
+ case 20:
+ return "Not a directory";
+ case 21:
+ return "Is a directory";
+ case 22:
+ return "Invalid argument";
+ case 23:
+ return "File table overflow";
+ case 24:
+ return "Too many open files";
+ case 25:
+ return "Not a typewriter";
+ case 26:
+ return "Text file busy";
+ case 27:
+ return "File too large";
+ case 28:
+ return "No space left on device";
+ case 29:
+ return "Illegal seek";
+ case 30:
+ return "Read-only file system";
+ case 31:
+ return "Too many links";
+ case 32:
+ return "Broken pipe";
+ case 33:
+ return "Math argument out of domain of func";
+ case 34:
+ return "Math result not representable";
+ default:
+ break;
+ }
+ return "Unknown";
+}
diff --git a/Src/Network/base/DriverConfiguration.h b/Src/Network/base/DriverConfiguration.h
new file mode 100644
index 0000000..b2fd44a
--- /dev/null
+++ b/Src/Network/base/DriverConfiguration.h
@@ -0,0 +1,239 @@
+/*
+ * 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 component provides helper tools to deal with USB endpoints.
+ */
+/*----------------------------------------------------------*/
+#ifndef DRIVERCONFIGURATION_H
+#define DRIVERCONFIGURATION_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /*----------------------------------------------------------*/
+ /*! \brief Checks if the given USB device instance exists.
+ *
+ * \param deviceInstance - The device instance of the USB INIC, starting at 0 for the first instance.
+ *
+ * \return true: Device exists.
+ * \return false: Device does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool ExistsUsbDeviceInstance( uint8_t deviceInstance );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Checks if the given MLB device instance exists.
+ *
+ * \param deviceInstance - The device instance of the MLB INIC, starting at 0 for the first instance.
+ *
+ * \return true: Device exists.
+ * \return false: Device does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool ExistsMlbDeviceInstance( uint8_t deviceInstance );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Checks if the given I2C device instance exists.
+ *
+ * \param deviceInstance - The device instance of the I2C INIC, starting at 0 for the first instance.
+ *
+ * \return true: Device exists.
+ * \return false: Device does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool ExistsI2CDeviceInstance( uint8_t deviceInstance );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retreives the Linux character device names for the given USB device instance and the endpoint address.
+ *
+ * \note If the given buffer is too small to hold the whole path, the string is truncated and not useable!
+ *
+ * \param deviceInstance - The device instance of the USB INIC, starting at 0 for the first instance.
+ * \param endpointAddress - The USB endpoint address, RX endpoints starting with upper bit set (0x8X).
+ * \param deviceName - [in,out] Given buffer will be filled with device name (starting with /dev/).
+ * \param deviceNameLength - The length of the given deviceName buffer in bytes.
+ * \param systemName - [in,out] Given buffer will be filled with system name (starting with /sys/).
+ * \param systemNameLength - The length of the given systemName buffer in bytes.
+ * \param linkName - [in,out] Given buffer will be filled with the string needed to register this device to an AIM
+ * \param linkNameLength - The length of the given linkName buffer in bytes.
+ *
+ * \return true: Operation was successful.
+ * \return false: Operation failed, device or endpoint does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool GetUsbDeviceNames( uint8_t deviceInstance, uint8_t endpointAddress, char *deviceName,
+ uint16_t deviceNameLength, char *systemName, uint16_t systemNameLength, char *linkName,
+ uint16_t linkNameLength );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retreives the Linux character device names for the given MLB device instance and the endpoint address.
+ *
+ * \note If the given buffer is too small to hold the whole path, the string is truncated and not useable!
+ *
+ * \param deviceInstance - The device instance of the USB INIC, starting at 0 for the first instance.
+ * \param mlbChannelAddress - The MLB channel address
+ * \param deviceName - [in,out] Given buffer will be filled with device name (starting with /dev/).
+ * \param deviceNameLength - The length of the given deviceName buffer in bytes.
+ * \param systemName - [in,out] Given buffer will be filled with system name (starting with /sys/).
+ * \param systemNameLength - The length of the given systemName buffer in bytes.
+ * \param linkName - [in,out] Given buffer will be filled with the string needed to register this device to an AIM
+ * \param linkNameLength - The length of the given linkName buffer in bytes.
+ *
+ * \return true: Operation was successful.
+ * \return false: Operation failed, device or endpoint does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool GetMlbDeviceNames( uint8_t deviceInstance, uint8_t mlbChannelAddress, char *deviceName,
+ uint16_t deviceNameLength, char *systemName, uint16_t systemNameLength, char *linkName,
+ uint16_t linkNameLength );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Retreives the Linux character device names for the given I2C device instance and the endpoint address.
+ *
+ * \note If the given buffer is too small to hold the whole path, the string is truncated and not useable!
+ *
+ * \param deviceInstance - The device instance of the I2C INIC, starting at 0 for the first instance.
+ * \param isTx - true, if the names for transmission path should be retrieved, otherwise for the reception path.
+ * \param deviceName - [in,out] Given buffer will be filled with device name (starting with /dev/).
+ * \param deviceNameLength - The length of the given deviceName buffer in bytes.
+ * \param systemName - [in,out] Given buffer will be filled with system name (starting with /sys/).
+ * \param systemNameLength - The length of the given systemName buffer in bytes.
+ * \param linkName - [in,out] Given buffer will be filled with the string needed to register this device to an AIM
+ * \param linkNameLength - The length of the given linkName buffer in bytes.
+ *
+ * \return true: Operation was successful.
+ * \return false: Operation failed, device or endpoint does not exist.
+ */
+ /*----------------------------------------------------------*/
+ bool GetI2CDeviceNames( uint8_t deviceInstance, bool isTx, char *deviceName, uint16_t deviceNameLength,
+ char *systemName, uint16_t systemNameLength, char *linkName, uint16_t linkNameLength );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Closes the MOST channel.
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool CloseMostChannel( const char *device );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures the MOST channel.
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ * \param mostType - The MOST data type (control, asynchron, synchron, isochron).
+ * \param direction - The direction of the stream (directionRX, directionTX).
+ * \param numBuf - The amount of buffers.
+ * \param bufSize - The size of each buffer in bytes.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureMostChannel( const char *device, EPDataType_t mostType, EPDirection_t direction, uint32_t numBuf,
+ uint32_t bufSize );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures the isochronous channel of a device.
+ * \note This function has to be called before ConfigureMostChannel!
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ * \param subbufferSize - The amount of bytes for a single subbuffer (eg. 188 or 196 bytes).
+ * \param packetsPerTransaction - The amount of ischronous packets per transaction.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureIsocChannel( const char *device, uint32_t subbufferSize, uint32_t packetsPerTransaction );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Configures the Synchronous channel of a device.
+ * \note This function has to be called before ConfigureMostChannel!
+ *
+ * \param device - The system path to configure the MOST device (starting with "/sys/").
+ * \param syncBlockWidth - The bandwidth of a single synchronous frame. Ignored if not sync channel.
+ * \param amounOfSyncFrames - The amount of synchronous frames per USB packet. Ignored if not sync channel.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool ConfigureSyncChannel( const char *device, uint32_t syncBlockWidth, uint32_t amounOfSyncFrames );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a character device for the given device's link name.
+ *
+ * \param linkName - [in] Link name, which is needed to register this device to an AIM.
+ * \param deviceName - [in,out] Device name (starting with /dev/).
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool LinkToCharacterDevice( const char *linkName, const char *deviceName );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a audio device (ALSA) for the given device's link name.
+ *
+ * \param linkName - [in] Link name, which is needed to register this device to an AIM.
+ * \param subBufferSize - [in] The amount of bytes for all channels of this connection on the MOST.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool LinkToAudioDevice( const char *linkName, uint16_t subBufferSize );
+
+ /*----------------------------------------------------------*/
+ /*! \brief Creates a Video for Linux device (V4L) for the given device's link name.
+ *
+ * \param linkName - [in] Link name, which is needed to register this device to an AIM.
+ *
+ * \return True if no error
+ */
+ /*----------------------------------------------------------*/
+ bool LinkToVideoForLinuxDevice( const char *linkName );
+
+
+ /*----------------------------------------------------------*/
+ /*! \brief Parsed the global errno variable and generate a human readable error description out of it.
+ *
+ * \return Zero terminated error description string.
+ */
+ /*----------------------------------------------------------*/
+ const char *GetErrnoString();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //DRIVERCONFIGURATION_H