1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for NMT-CN-Userspace-Module
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplNmtCnu.c,v $
56 $Revision: 1.6 $ $Date: 2008/10/17 15:32:32 $
63 -------------------------------------------------------------------------
67 2006/06/09 k.t.: start of the implementation
69 ****************************************************************************/
72 #include "user/EplNmtCnu.h"
73 #include "user/EplDlluCal.h"
75 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
77 /***************************************************************************/
80 /* G L O B A L D E F I N I T I O N S */
83 /***************************************************************************/
85 //---------------------------------------------------------------------------
87 //---------------------------------------------------------------------------
89 //---------------------------------------------------------------------------
91 //---------------------------------------------------------------------------
95 unsigned int m_uiNodeId;
96 tEplNmtuCheckEventCallback m_pfnCheckEventCb;
100 //---------------------------------------------------------------------------
101 // modul globale vars
102 //---------------------------------------------------------------------------
104 static tEplNmtCnuInstance EplNmtCnuInstance_g;
106 //---------------------------------------------------------------------------
107 // local function prototypes
108 //---------------------------------------------------------------------------
110 static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
112 static BOOL EplNmtCnuNodeIdList(BYTE* pbNmtCommandDate_p);
114 static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
118 //=========================================================================//
120 // P U B L I C F U N C T I O N S //
122 //=========================================================================//
124 //---------------------------------------------------------------------------
126 // Function: EplNmtCnuInit
128 // Description: init the first instance of the module
132 // Parameters: uiNodeId_p = NodeId of the local node
135 // Returns: tEplKernel = errorcode
140 //---------------------------------------------------------------------------
141 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
145 Ret = EplNmtCnuAddInstance(uiNodeId_p);
150 //---------------------------------------------------------------------------
152 // Function: EplNmtCnuAddInstance
154 // Description: init the add new instance of the module
158 // Parameters: uiNodeId_p = NodeId of the local node
161 // Returns: tEplKernel = errorcode
166 //---------------------------------------------------------------------------
167 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
171 Ret = kEplSuccessful;
173 // reset instance structure
174 EPL_MEMSET(&EplNmtCnuInstance_g, 0, sizeof (EplNmtCnuInstance_g));
177 EplNmtCnuInstance_g.m_uiNodeId = uiNodeId_p;
179 // register callback-function for NMT-commands
180 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
181 Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
183 kEplDllAsndFilterLocal);
191 //---------------------------------------------------------------------------
193 // Function: EplNmtCnuDelInstance
195 // Description: delte instance of the module
202 // Returns: tEplKernel = errorcode
207 //---------------------------------------------------------------------------
208 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
212 Ret = kEplSuccessful;
214 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
215 // deregister callback function from DLL
216 Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
218 kEplDllAsndFilterNone);
224 //---------------------------------------------------------------------------
226 // Function: EplNmtCnuSendNmtRequest
228 // Description: Send an NMT-Request to the MN
232 // Parameters: uiNodeId_p = NodeId of the local node
233 // NmtCommand_p = requested NMT-Command
236 // Returns: tEplKernel = errorcode
241 //---------------------------------------------------------------------------
242 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(
243 unsigned int uiNodeId_p,
244 tEplNmtCommand NmtCommand_p)
247 tEplFrameInfo NmtRequestFrameInfo;
248 tEplFrame NmtRequestFrame;
251 Ret = kEplSuccessful;
254 EPL_MEMSET(&NmtRequestFrame.m_be_abDstMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abDstMac)); // set by DLL
255 EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac)); // set by DLL
256 AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType, EPL_C_DLL_ETHERTYPE_EPL);
257 AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (BYTE) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
258 AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType, (BYTE)kEplMsgTypeAsnd);
259 AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId, (BYTE) kEplDllAsndNmtRequest);
260 AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bNmtCommandId,
262 AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId,
263 (BYTE)uiNodeId_p); // target for the nmt command
264 EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_abNmtCommandData[0], 0x00, sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_abNmtCommandData));
268 // build info-structure
269 NmtRequestFrameInfo.m_NetTime.m_dwNanoSec = 0;
270 NmtRequestFrameInfo.m_NetTime.m_dwSec = 0;
271 NmtRequestFrameInfo.m_pFrame = &NmtRequestFrame;
272 NmtRequestFrameInfo.m_uiFrameSize = EPL_C_DLL_MINSIZE_NMTREQ; // sizeof(NmtRequestFrame);
275 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
276 Ret = EplDlluCalAsyncSend(&NmtRequestFrameInfo, // pointer to frameinfo
277 kEplDllAsyncReqPrioNmt); // priority
285 //---------------------------------------------------------------------------
287 // Function: EplNmtCnuRegisterStateChangeCb
289 // Description: register Callback-function go get informed about a
290 // NMT-Change-State-Event
294 // Parameters: pfnEplNmtStateChangeCb_p = functionpointer
297 // Returns: tEplKernel = errorcode
302 //---------------------------------------------------------------------------
304 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuRegisterCheckEventCb(
305 tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p)
309 Ret = kEplSuccessful;
311 // save callback-function in modul global var
312 EplNmtCnuInstance_g.m_pfnCheckEventCb = pfnEplNmtCheckEventCb_p;
318 //=========================================================================//
320 // P R I V A T E F U N C T I O N S //
322 //=========================================================================//
325 //---------------------------------------------------------------------------
327 // Function: EplNmtCnuCommandCb
329 // Description: callback funktion for NMT-Commands
333 // Parameters: pFrameInfo_p = Frame with the NMT-Commando
336 // Returns: tEplKernel = errorcode
341 //---------------------------------------------------------------------------
342 static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p)
344 tEplKernel Ret = kEplSuccessful;
345 tEplNmtCommand NmtCommand;
347 tEplNmtEvent NmtEvent = kEplNmtEventNoEvent;
350 if(pFrameInfo_p == NULL)
352 Ret = kEplNmtInvalidFramePointer;
356 NmtCommand = EplNmtCnuGetNmtCommand(pFrameInfo_p);
362 //------------------------------------------------------------------------
363 // plain NMT state commands
364 case kEplNmtCmdStartNode:
365 { // send NMT-Event to state maschine kEplNmtEventStartNode
366 NmtEvent = kEplNmtEventStartNode;
370 case kEplNmtCmdStopNode:
371 { // send NMT-Event to state maschine kEplNmtEventStopNode
372 NmtEvent = kEplNmtEventStopNode;
376 case kEplNmtCmdEnterPreOperational2:
377 { // send NMT-Event to state maschine kEplNmtEventEnterPreOperational2
378 NmtEvent = kEplNmtEventEnterPreOperational2;
382 case kEplNmtCmdEnableReadyToOperate:
383 { // send NMT-Event to state maschine kEplNmtEventEnableReadyToOperate
384 NmtEvent = kEplNmtEventEnableReadyToOperate;
388 case kEplNmtCmdResetNode:
389 { // send NMT-Event to state maschine kEplNmtEventResetNode
390 NmtEvent = kEplNmtEventResetNode;
394 case kEplNmtCmdResetCommunication:
395 { // send NMT-Event to state maschine kEplNmtEventResetCom
396 NmtEvent = kEplNmtEventResetCom;
400 case kEplNmtCmdResetConfiguration:
401 { // send NMT-Event to state maschine kEplNmtEventResetConfig
402 NmtEvent = kEplNmtEventResetConfig;
406 case kEplNmtCmdSwReset:
407 { // send NMT-Event to state maschine kEplNmtEventSwReset
408 NmtEvent = kEplNmtEventSwReset;
412 //------------------------------------------------------------------------
413 // extended NMT state commands
415 case kEplNmtCmdStartNodeEx:
417 // check if own nodeid is in EPL node list
418 fNodeIdInList = EplNmtCnuNodeIdList(&(pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]));
419 if(fNodeIdInList != FALSE)
420 { // own nodeid in list
421 // send event to process command
422 NmtEvent = kEplNmtEventStartNode;
427 case kEplNmtCmdStopNodeEx:
428 { // check if own nodeid is in EPL node list
429 fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
430 if(fNodeIdInList != FALSE)
431 { // own nodeid in list
432 // send event to process command
433 NmtEvent = kEplNmtEventStopNode;
438 case kEplNmtCmdEnterPreOperational2Ex:
439 { // check if own nodeid is in EPL node list
440 fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
441 if(fNodeIdInList != FALSE)
442 { // own nodeid in list
443 // send event to process command
444 NmtEvent = kEplNmtEventEnterPreOperational2;
449 case kEplNmtCmdEnableReadyToOperateEx:
450 { // check if own nodeid is in EPL node list
451 fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
452 if(fNodeIdInList != FALSE)
453 { // own nodeid in list
454 // send event to process command
455 NmtEvent = kEplNmtEventEnableReadyToOperate;
460 case kEplNmtCmdResetNodeEx:
461 {// check if own nodeid is in EPL node list
462 fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
463 if(fNodeIdInList != FALSE)
464 { // own nodeid in list
465 // send event to process command
466 NmtEvent = kEplNmtEventResetNode;
471 case kEplNmtCmdResetCommunicationEx:
472 { // check if own nodeid is in EPL node list
473 fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
474 if(fNodeIdInList != FALSE)
475 { // own nodeid in list
476 // send event to process command
477 NmtEvent = kEplNmtEventResetCom;
482 case kEplNmtCmdResetConfigurationEx:
483 { // check if own nodeid is in EPL node list
484 fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
485 if(fNodeIdInList != FALSE)
486 { // own nodeid in list
487 // send event to process command
488 NmtEvent = kEplNmtEventResetConfig;
493 case kEplNmtCmdSwResetEx:
494 { // check if own nodeid is in EPL node list
495 fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
496 if(fNodeIdInList != FALSE)
497 { // own nodeid in list
498 // send event to process command
499 NmtEvent = kEplNmtEventSwReset;
504 //------------------------------------------------------------------------
505 // NMT managing commands
507 // TODO: add functions to process managing command (optional)
509 case kEplNmtCmdNetHostNameSet:
514 case kEplNmtCmdFlushArpEntry:
519 //------------------------------------------------------------------------
522 // TODO: forward event with infos to the application (optional)
524 case kEplNmtCmdPublishConfiguredCN:
529 case kEplNmtCmdPublishActiveCN:
534 case kEplNmtCmdPublishPreOperational1:
539 case kEplNmtCmdPublishPreOperational2:
544 case kEplNmtCmdPublishReadyToOperate:
549 case kEplNmtCmdPublishOperational:
554 case kEplNmtCmdPublishStopped:
559 case kEplNmtCmdPublishEmergencyNew:
564 case kEplNmtCmdPublishTime:
569 //-----------------------------------------------------------------------
571 // -> requested command not supported by MN
572 case kEplNmtCmdInvalidService:
575 // TODO: errorevent to application
579 //------------------------------------------------------------------------
583 Ret = kEplNmtUnknownCommand;
587 }// end of switch(NmtCommand)
589 if (NmtEvent != kEplNmtEventNoEvent)
591 if (EplNmtCnuInstance_g.m_pfnCheckEventCb != NULL)
593 Ret = EplNmtCnuInstance_g.m_pfnCheckEventCb(NmtEvent);
594 if (Ret == kEplReject)
596 Ret = kEplSuccessful;
599 else if (Ret != kEplSuccessful)
604 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
605 Ret = EplNmtuNmtEvent(NmtEvent);
614 //---------------------------------------------------------------------------
616 // Function: EplNmtCnuGetNmtCommand()
618 // Description: returns the NMT-Command from the frame
622 // Parameters: pFrameInfo_p = pointer to the Frame
623 // with the NMT-Command
626 // Returns: tEplNmtCommand = NMT-Command
631 //---------------------------------------------------------------------------
632 static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p)
634 tEplNmtCommand NmtCommand;
635 tEplNmtCommandService* pNmtCommandService;
637 pNmtCommandService = &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService;
639 NmtCommand = (tEplNmtCommand)AmiGetByteFromLe(&pNmtCommandService->m_le_bNmtCommandId);
644 //---------------------------------------------------------------------------
646 // Function: EplNmtCnuNodeIdList()
648 // Description: check if the own nodeid is set in EPL Node List
652 // Parameters: pbNmtCommandDate_p = pointer to the data of the NMT Command
655 // Returns: BOOL = TRUE if nodeid is set in EPL Node List
656 // FALSE if nodeid not set in EPL Node List
661 //---------------------------------------------------------------------------
662 static BOOL EplNmtCnuNodeIdList(BYTE* pbNmtCommandDate_p)
665 unsigned int uiByteOffset;
669 // get byte-offset of the own nodeid in NodeIdList
671 uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3);
673 bBitOffset = (BYTE) EplNmtCnuInstance_g.m_uiNodeId % 8;
675 bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
676 if((bNodeListByte & bBitOffset) == 0)
678 fNodeIdInList = FALSE;
682 fNodeIdInList = TRUE;
685 return fNodeIdInList;
688 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)