//------------------------------------------------------------------------------
static tOplkError processNodeEvent(tOplkApiEventType EventType_p,
                                   tOplkApiEventArg* pEventArg_p,
                                   void* pUserArg_p)
{
    tOplkApiEventNode*   pNode = &pEventArg_p->nodeEvent;

    UNUSED_PARAMETER(EventType_p);
    UNUSED_PARAMETER(pUserArg_p);

    // check additional argument
    switch (pNode->nodeEvent)
    {
        case kNmtNodeEventCheckConf:
            PRINTF("NodeEvent: (Node=%u, CheckConf)\n", pNode->nodeId);
            break;

        case kNmtNodeEventUpdateConf:
            PRINTF("NodeEvent: (Node=%u, UpdateConf)\n", pNode->nodeId);
            break;

        case kNmtNodeEventNmtState:
            PRINTF("NodeEvent: (Node=%u, NmtState=%s)\n",
                   pNode->nodeId,
                   debugstr_getNmtStateStr(pNode->nmtState));
            break;

        case kNmtNodeEventError:
            PRINTF("NodeEvent: (Node=%u): Error=%s (0x%.4X)\n",
                   pNode->nodeId,
                   debugstr_getEmergErrCodeStr(pNode->errorCode),
                   pNode->errorCode);
            break;

        case kNmtNodeEventFound:
            PRINTF("NodeEvent: (Node=%u, Found)\n", pNode->nodeId);
            break;

        default:
            break;
    }
    return kErrorOk;
}
//------------------------------------------------------------------------------
tOplkError ProcessThread::processNodeEvent(tOplkApiEventType eventType_p,
                                           tOplkApiEventArg* pEventArg_p,
                                           void* pUserArg_p)
{
    tOplkApiEventNode*   pNode = &pEventArg_p->nodeEvent;
    tOplkError           ret = kErrorOk;

    UNUSED_PARAMETER(eventType_p);
    UNUSED_PARAMETER(pUserArg_p);
    // printf("AppCbEvent(Node): NodeId=%u Event=0x%02X\n",
    //        pEventArg_p->nodeEvent.nodeId, pEventArg_p->nodeEvent.nodeEvent);
    // check additional argument
    switch (pEventArg_p->nodeEvent.nodeEvent)
    {
        case kNmtNodeEventCheckConf:
#if !defined(CONFIG_INCLUDE_CFM)
            // Configuration Manager is not available,
            // so configure CycleLen (object 0x1006) on CN
            tSdoComConHdl SdoComConHdl;

            // update object 0x1006 on CN
            ret = oplk_writeObject(&SdoComConHdl, pEventArg_p->nodeEvent.nodeId,
                                   0x1006, 0x00, &cycleLen_g, 4,
                                   kSdoTypeAsnd, NULL);
            if (ret == kErrorApiTaskDeferred)
            {   // SDO transfer started
                ret = kErrorReject;
            }
            else if (ret == kErrorOk)
            {   // local OD access (should not occur)
                printf("AppCbEvent(Node) write to local OD\n");
            }
            else
            {   // error occured

                ret = oplk_freeSdoChannel(SdoComConHdl);
                SdoComConHdl = 0;

                ret = oplk_writeObject(&SdoComConHdl, pEventArg_p->nodeEvent.nodeId,
                                       0x1006, 0x00, &cycleLen_g, 4,
                                       kSdoTypeAsnd, NULL);
                if (ret == kErrorApiTaskDeferred)
                {   // SDO transfer started
                    ret = kErrorReject;
                }
                else
                {
                    printf("AppCbEvent(Node): oplk_writeObject() returned 0x%03X", ret);
                }
            }
#endif

            sigPrintLog(QString("Node Event: (Node=%2, CheckConf)")
                                .arg(pEventArg_p->nodeEvent.nodeId, 0, 10));
            break;

        case kNmtNodeEventUpdateConf:
            sigPrintLog(QString("Node Event: (Node=%1, UpdateConf)")
                                .arg(pEventArg_p->nodeEvent.nodeId, 0, 10));
            break;

        case kNmtNodeEventFound:
            pProcessThread_g->sigNodeAppeared(pEventArg_p->nodeEvent.nodeId);
            break;

        case kNmtNodeEventNmtState:
            switch (pEventArg_p->nodeEvent.nmtState)
            {
                case kNmtGsOff:
                case kNmtGsInitialising:
                case kNmtGsResetApplication:
                case kNmtGsResetCommunication:
                case kNmtGsResetConfiguration:
                case kNmtCsNotActive:
                    pProcessThread_g->sigNodeDisappeared(pEventArg_p->nodeEvent.nodeId);
                    break;

                case kNmtCsPreOperational1:
                case kNmtCsPreOperational2:
                case kNmtCsReadyToOperate:
                    pProcessThread_g->sigNodeAppeared(pEventArg_p->nodeEvent.nodeId);
                    pProcessThread_g->sigNodeStatus(pEventArg_p->nodeEvent.nodeId, 1);
                    break;

                case kNmtCsOperational:
                    pProcessThread_g->sigNodeAppeared(pEventArg_p->nodeEvent.nodeId);
                    pProcessThread_g->sigNodeStatus(pEventArg_p->nodeEvent.nodeId, 2);
                    break;

                case kNmtCsBasicEthernet:
                case kNmtCsStopped:
                default:
                    pProcessThread_g->sigNodeStatus(pEventArg_p->nodeEvent.nodeId, -1);
                    break;
            }
            break;

        case kNmtNodeEventError:
            pProcessThread_g->sigNodeStatus(pEventArg_p->nodeEvent.nodeId, -1);
            sigPrintLog(QString("AppCbEvent (Node=%1): Error = %2 (0x%3)")
                                .arg(pEventArg_p->nodeEvent.nodeId, 0, 10)
                                .arg(debugstr_getEmergErrCodeStr(pEventArg_p->nodeEvent.errorCode))
                                .arg(pEventArg_p->nodeEvent.errorCode, 4, 16, QLatin1Char('0')));
            break;

        case kNmtNodeEventAmniReceived:
            sigPrintLog(QString("AppCbEvent (Node=%1): received ActiveManagingNodeIndication")
                                .arg(pEventArg_p->nodeEvent.nodeId, 0, 10));
            break;

        default:
            break;
    }
    return kErrorOk;
}