Example #1
0
        /// <summary>
        /// Update the self test mode.
        /// </summary>
        /// <remarks>This call is used to check whether communication with the VCU has been lost.</remarks>
        /// <param name="selfTestMode">The required self test mode.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the m_SelfTestMarshal.UpdateSTMode() method is not
        /// CommunicationError.Success.</exception>
        public void UpdateSTMode(SelfTestMode selfTestMode)
        {
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.UpdateSTMode() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = m_SelfTestMarshal.UpdateSTMode((Int16)selfTestMode);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.UpdateSTMode()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.UpdateSTMode_t updateSTMode = new DebugMode.UpdateSTMode_t(selfTestMode, errorCode);
                DebugMode.Write(updateSTMode.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.UpdateSTMode()", errorCode);
            }
        }
Example #2
0
        /// <summary>
        /// Execute the self tests that are defined in the current list.
        /// </summary>
        /// <param name="truckInformation">The truck to which the self tests apply. This does not apply on the CTA project as separate self-tests are
        /// set up for each truck.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the m_SelfTestMarshal.ExecuteSTTestList() method is not
        /// CommunicationError.Success.</exception>
        public void ExecuteSTTestList(TruckInformation truckInformation)
        {
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.ExecuteSTTestList() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = m_SelfTestMarshal.ExecuteSTTestList((short)truckInformation);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.ExecuteSTTestList()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.ExecuteSTTestList_t executeSTTestList = new DebugMode.ExecuteSTTestList_t(truckInformation, errorCode);
                DebugMode.Write(executeSTTestList.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.ExecuteSTTestList()", errorCode);
            }
        }
Example #3
0
        /// <summary>
        /// Run the predefined self tests associated with the specified test list identifier, these tests are defined in the data dictionary.
        /// </summary>
        /// <param name="testListIdentifier">The test list identifier of the predefined self tests that are to be executed.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the m_SelfTestMarshal.RunPredefinedSTTests() method is
        /// not CommunicationError.Success.</exception>
        public void RunPredefinedSTTests(short testListIdentifier)
        {
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.RunPredefinedSTTests() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = m_SelfTestMarshal.RunPredefinedSTTests(testListIdentifier);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.RunPredefinedSTTests()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.RunPredefinedSTTests_t runPredefinedSTTests = new DebugMode.RunPredefinedSTTests_t(testListIdentifier, errorCode);
                DebugMode.Write(runPredefinedSTTests.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.RunPredefinedSTTests()", errorCode);
            }
        }
Example #4
0
        /// <summary>
        /// Update the number of times that the selected tests are to be run.
        /// </summary>
        /// <param name="loopCount">The number of cycles/loops of the defined tests that are to be performed.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the m_SelfTestMarshal.UpdateSTLoopCount() method is not
        /// CommunicationError.Success.</exception>
        public void UpdateSTLoopCount(short loopCount)
        {
            // Check that the function delegate has been initialized.
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.UpdateSTLoopCount() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = m_SelfTestMarshal.UpdateSTLoopCount(loopCount);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.UpdateSTLoopCount()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.UpdateSTLoopCount_t updateSTLoopCount = new DebugMode.UpdateSTLoopCount_t(loopCount, errorCode);
                DebugMode.Write(updateSTLoopCount.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.UpdateSTLoopCount()", errorCode);
            }
        }
Example #5
0
        /// <summary>
        /// Exit the self test task.
        /// </summary>
        /// <remarks>This request will end the self test process on the VCU.</remarks>
        /// <param name="result">The result of the call. A value of: (1) 1 represents success; (2) indicates that the error message defined by the
        /// <paramref name="reason"/> parameter applies and (3) represents an unknown error.</param>
        /// <param name="reason">A value of 1 represents success; otherwise, the value is mapped to the <c>ERRID</c> field of the
        /// <c>SELFTESTERRMESS</c> table
        /// of the data dictionary in order to determine the error message returned from the VCU.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the m_SelfTestMarshal.ExitSelfestTask() method is not
        /// CommunicationError.Success.</exception>
        public void ExitSelfTestTask(out short result, out short reason)
        {
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.ExitSelfTestTask() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = m_SelfTestMarshal.ExitSelfTestTask(out result, out reason);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.ExitSelfTestTask()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.ExitSelfTestTask_t exitSelfTestTask = new DebugMode.ExitSelfTestTask_t(result, reason, errorCode);
                DebugMode.Write(exitSelfTestTask.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.ExitSelfestTask()", errorCode);
            }
        }
Example #6
0
        /// <summary>
        /// Get the self test special message.
        /// </summary>
        /// <param name="result">The result of the call. A value of: (1) 1 represents success; (2) indicates that the error message defined by the
        /// <paramref name="reason"/> parameter applies and (3) represents an unknown error.</param>
        /// <param name="reason">A value of 1 represents success; otherwise, the value is mapped to the <c>ERRID</c> field of the
        /// <c>SELFTESTERRMESS</c> table
        /// of the data dictionary in order to determine the error message returned from the VCU.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the m_SelfTestMarshal.GetSelfTestSpecialMessage()
        /// method is not CommunicationError.Success.</exception>
        public void GetSelfTestSpecialMessage(out short result, out short reason)
        {
            // Check that the function delegate has been initialized.
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.GetSelfTestSpecialMessage() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = m_SelfTestMarshal.GetSelfTestSpecialMessage(out result, out reason);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.GetSelfTestSpecialMessage()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.GetSelfTestSpecialMessage_t getSelfTestSpecialMessage = new DebugMode.GetSelfTestSpecialMessage_t(result, reason, errorCode);
                DebugMode.Write(getSelfTestSpecialMessage.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.GetSelfTestSpecialMessage()", errorCode);
            }
        }
Example #7
0
        /// <summary>
        /// Write the specified data to the watch variable specified by the <paramref name="dictionaryIndex"/> parameter.
        /// </summary>
        /// <param name="dictionaryIndex">The dictionary index.</param>
        /// <param name="dataType">The data type.</param>
        /// <param name="data">The data.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the PTUDLL32.CloseCommunication() method is not
        /// CommunicationError.Success.</exception>
        public void SendVariable(short dictionaryIndex, short dataType, double data)
        {
            Debug.Assert(m_MutexCommuncationInterface != null, "CommunicationWatch.SendVariable() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = (CommunicationError)m_WatchClockMarshal.SendVariable(dictionaryIndex, dataType, data);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException(Resources.EMSendVariableFailed, errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException(Resources.EMSendVariableFailed, errorCode);
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.SendVariable_t sendVariable = new DebugMode.SendVariable_t(dictionaryIndex, dataType, data, errorCode);
                DebugMode.Write(sendVariable.ToXML());
            }
        }
Example #8
0
        /// <summary>
        /// Map the watch identifiers listed in <paramref name="watchElementList"/> to the watch element array monitored by the target hardware.
        /// </summary>
        /// <remarks> The number of watch identifiers in the list must not exceed <c>WatchSize</c>.</remarks>
        /// <param name="watchElementList">The list containing the watch identifiers that are to be mapped to each element of the watch element array.
        /// </param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the PTUDLL32.SetWatchElements() method is not
        /// CommunicationError.Success.</exception>
        public void SetWatchElements(List <short> watchElementList)
        {
            Debug.Assert(m_SetWatchElements != null, "CommunicationWatch.SetWatchElements() - [m_SetWatchElementDelegates != null]");
            Debug.Assert(m_MutexCommuncationInterface != null, "CommunicationWatch.SetWatchElements() - [m_MutexCommuncationInterface != null]");

            // Skip, if the parameter isn't defined.
            if (watchElementList == null)
            {
                return;
            }

            Debug.Assert(watchElementList.Count <= Parameter.WatchSize,
                         "CommunicationWatch.SetWatchElements - [watchElementList.Count <= Parameter.WatchSize]");

            short[] watchElements = new short[Parameter.WatchSize];
            Array.Copy(watchElementList.ToArray(), watchElements, watchElementList.Count);

            // Send the mapping to the target hardware.
            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = (CommunicationError)m_SetWatchElements(watchElements);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException(Resources.EMSetWatchElementsFailed, errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.SetWatchElements_t setWatchElements = new DebugMode.SetWatchElements_t(watchElements, errorCode);
                DebugMode.Write(setWatchElements.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException(Resources.EMSetWatchElementsFailed, errorCode);
            }

            // Keep a record up the new mapping beween the each element index and the watch identifier.
            for (short elementIndex = 0; elementIndex < Parameter.WatchSize; elementIndex++)
            {
                m_WatchElements[elementIndex].WatchIdentifier = watchElements[elementIndex];

                // Required to map between the watch identifier and the element index.
                m_WatchElements[elementIndex].ElementIndex = elementIndex;
            }
        }
Example #9
0
        /// <summary>
        /// Retrieve the watch elements from the target hardware.
        /// </summary>
        /// <remarks>The watch elements are the watch values that are being monitored by the target hardware as defined by the
        /// <c>SetWatchElements()> method.</c></remarks>
        /// <returns>The retrieved watch element table, if successful; otherwise, null.</returns>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the VcuCommunication32/VcuCommunication64
        /// UpdateElements() method is not CommunicationError.Success.</exception>
        public WatchElement_t[] UpdateWatchElements(bool forceUpdate)
        {
            Debug.Assert(m_UpdateWatchElements != null, "CommunicationWatch.UpdateWatchElements() - [m_UpdateWatchElementsDelegate != null]");
            Debug.Assert(m_MutexCommuncationInterface != null, "CommunicationWatch.UpdateWatchElements() - [m_MutexCommuncationInterface != null]");

            WatchElement_t[] watchElements  = new WatchElement_t[Parameter.WatchSize];
            double[]         watchValues    = new double[Parameter.WatchSize];
            short[]          watchDataTypes = new short[Parameter.WatchSize];

            short forceUpdateAsShort     = (forceUpdate == true) ? ForceUpdateTrue : ForceUpdateFalse;
            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = (CommunicationError)m_UpdateWatchElements(forceUpdateAsShort, watchValues, watchDataTypes);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException(Resources.EMUpdateWatchElementsFailed, errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.UpdateWatchElements_t updateWatchElements = new DebugMode.UpdateWatchElements_t(forceUpdateAsShort, watchValues,
                                                                                                          watchDataTypes, errorCode);
                DebugMode.Write(updateWatchElements.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException(Resources.EMUpdateWatchElementsFailed, errorCode);
            }

            // Map the values retrieved from the target hardware into the watch element table.
            for (short elementIndex = 0; elementIndex < Parameter.WatchSize; elementIndex++)
            {
                watchElements[elementIndex]                 = new WatchElement_t();
                watchElements[elementIndex].Value           = watchValues[elementIndex];
                watchElements[elementIndex].DataType        = watchDataTypes[elementIndex];
                watchElements[elementIndex].WatchIdentifier = m_WatchElements[elementIndex].WatchIdentifier;
                watchElements[elementIndex].ElementIndex    = elementIndex;
            }
            return(watchElements);
        }
Example #10
0
        /// <summary>
        /// Get the self test results.
        /// </summary>
        /// <param name="resultAvailable">A flag to indicate whether a valid result is available. A value of 1 indicates that a valid result is
        /// available; otherwise,  0.</param>
        /// <param name="messageMode">The type of message returned from the VCU.</param>
        /// <param name="testIdentifier">The test result identifier; the interpretation of this value is dependent upon the message mode. For detailed
        /// messages, this value represents the self test identifier.</param>
        /// <param name="testCase">The test case number associated with the message.</param>
        /// <param name="testResult">Used with the passive and logic self tests to define whether the test passed or failed. A value of 1 indicates
        /// that the test passed; otherwise, the test failed.</param>
        /// <param name="truckInformation">An enumerator to define the truck information associated with the message.</param>
        /// <param name="variableCount">The number of variables associated with the message.</param>
        /// <param name="results">An array of <see cref="InteractiveResults_t"/> structures containing the value of each self test variable associated
        /// with the current interactive test.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the m_SelfTestMarshal.GetSelfTestResult() method is not
        /// CommunicationError.Success.</exception>
        /// <remarks>In C# the sizeof the InteractiveResults_t structure is 16 bytes as the size is rounded up to the nearest quad word. This is
        /// inconsistent with the size of the InteractiveResults_t structure - 12 bytes. To ensure that the results are
        /// interpreted correctly the results are passed as a byte array which is then mapped to an array of InteractiveResults structures.</remarks>
        public void GetSelfTestResult(out short resultAvailable, out MessageMode messageMode, out short testIdentifier, out short testCase,
                                      out short testResult, out TruckInformation truckInformation, out short variableCount,
                                      out InteractiveResults_t[] results)
        {
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.GetSelfTestResult() - [m_MutexCommuncationInterface != null]");

            results = new InteractiveResults_t[Parameter.WatchSizeInteractiveTest];

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = m_SelfTestMarshal.GetSelfTestResult(out resultAvailable, out messageMode, out testIdentifier, out testCase, out testResult,
                                                                out truckInformation, out variableCount, results);
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.GetSelfTestResult()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }


            if (DebugMode.Enabled == true)
            {
                DebugMode.GetSelfTestResult_t getSelfTestResult = new DebugMode.GetSelfTestResult_t(resultAvailable, messageMode, testIdentifier,
                                                                                                    testCase, testResult, truckInformation,
                                                                                                    variableCount, results, errorCode);
                DebugMode.Write(getSelfTestResult.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.GetSelfTestResult()", errorCode);
            }
        }
        /// <summary>
        /// Send an operator acknowledge message.
        /// </summary>
        /// <remarks>This request allows the operator to move to the next step of an interactive test.</remarks>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the PTUDLL32.SendOperatorAcknowledge() method
        /// is not CommunicationError.Success.</exception>
        public void SendOperatorAcknowledge()
        {
            // Check that the function delegate has been initialized.
            Debug.Assert(m_SendOperatorAcknowledge != null,
                         "CommunicationSelfTest.SendOperatorAcknowledge() - [m_SendOperatorAcknowledge != null]");
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.SendOperatorAcknowledge() - [m_MutexCommuncationInterface != null]");

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                errorCode = (CommunicationError)m_SendOperatorAcknowledge();
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.SendOperatorAcknowledge()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.SendOperatorAcknowledge_t sendOperatorAcknowledge = new DebugMode.SendOperatorAcknowledge_t(errorCode);
                DebugMode.Write(sendOperatorAcknowledge.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.SendOperatorAcknowledge()", errorCode);
            }
        }
        /// <summary>
        /// Get the self test results.
        /// </summary>
        /// <param name="resultAvailable">A flag to indicate whether a valid result is available. A value of 1 indicates that a valid result is
        /// available; otherwise,  0.</param>
        /// <param name="messageMode">The type of message returned from the VCU.</param>
        /// <param name="testIdentifier">The test result identifier; the interpretation of this value is dependent upon the message mode. For detailed
        /// messages, this value represents the self test identifier.</param>
        /// <param name="testCase">The test case number associated with the message.</param>
        /// <param name="testResult">Used with the passive and logic self tests to define whether the test passed or failed. A value of 1 indicates
        /// that the test passed; otherwise, the test failed.</param>
        /// <param name="truckInformation">An enumerator to define the truck information associated with the message.</param>
        /// <param name="variableCount">The number of variables associated with the message.</param>
        /// <param name="results">An array of <see cref="InteractiveResults_t"/> structures containing the value of each self test variable associated
        /// with the current interactive test.</param>
        /// <exception cref="CommunicationException">Thrown if the error code returned from the call to the PTUDLL32.GetSelfTestResult() method is not
        /// CommunicationError.Success.</exception>
        /// <remarks>In C# the sizeof the InteractiveResults_t structure is 16 bytes as the size is rounded up to the nearest quad word. This is
        /// inconsistent with the size of the InteractiveResults_t structure used in PTUDLL32.dll - 12 bytes. To ensure that the results are
        /// interpreted correctly the results are passed as a byte array which is then mapped to an array of InteractiveResults structures.</remarks>
        public unsafe void GetSelfTestResult(out short resultAvailable, out MessageMode messageMode, out short testIdentifier, out short testCase,
                                             out short testResult, out TruckInformation truckInformation, out short variableCount,
                                             out InteractiveResults_t[] results)
        {
            // Check that the function delegate has been initialized.
            Debug.Assert(m_GetSelfTestResult != null,
                         "CommunicationSelfTest.GetSelfTestResult() - [m_GetSelfTestResult != null]");
            Debug.Assert(m_MutexCommuncationInterface != null,
                         "CommunicationSelfTest.GetSelfTestResult() - [m_MutexCommuncationInterface != null]");

            results = new InteractiveResults_t[Parameter.WatchSizeInteractiveTest];
            int sizeOfInteractiveResultInPTUDLL32 = sizeof(double) + sizeof(int);

            byte[] interactiveResultsAsByteArray = new byte[Parameter.WatchSizeInteractiveTest * sizeOfInteractiveResultInPTUDLL32];

            CommunicationError errorCode = CommunicationError.UnknownError;

            try
            {
                m_MutexCommuncationInterface.WaitOne(DefaultMutexWaitDurationMs, false);
                unsafe
                {
                    fixed(byte *interactiveResults = &interactiveResultsAsByteArray[0])
                    {
                        errorCode = (CommunicationError)m_GetSelfTestResult(out resultAvailable, out messageMode,
                                                                            out testIdentifier, out testCase, out testResult,
                                                                            out truckInformation, out variableCount,
                                                                            interactiveResults);
                    }
                }
            }
            catch (Exception)
            {
                errorCode = CommunicationError.SystemException;
                throw new CommunicationException("CommunicationSelfTest.GetSelfTestResult()", errorCode);
            }
            finally
            {
                m_MutexCommuncationInterface.ReleaseMutex();
            }

            // Convert the byte array returned from the call to an array of InteractiveResults_t structures.
            int offset = 0;

            for (int index = 0; index < variableCount; index++)
            {
                offset = index * sizeOfInteractiveResultInPTUDLL32;
                results[index].Value = BitConverter.ToDouble(interactiveResultsAsByteArray, offset);
                results[index].Tag   = BitConverter.ToInt32(interactiveResultsAsByteArray, offset + sizeof(double));
            }

            if (DebugMode.Enabled == true)
            {
                DebugMode.GetSelfTestResult_t getSelfTestResult = new DebugMode.GetSelfTestResult_t(resultAvailable, messageMode, testIdentifier,
                                                                                                    testCase, testResult, truckInformation,
                                                                                                    variableCount, results, errorCode);
                DebugMode.Write(getSelfTestResult.ToXML());
            }

            if (errorCode != CommunicationError.Success)
            {
                throw new CommunicationException("CommunicationSelfTest.GetSelfTestResult()", errorCode);
            }
        }