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 //---------------------------------------------------------------------------
94 unsigned int m_uiNodeId;
95 tEplNmtuCheckEventCallback m_pfnCheckEventCb;
99 //---------------------------------------------------------------------------
100 // modul globale vars
101 //---------------------------------------------------------------------------
103 static tEplNmtCnuInstance EplNmtCnuInstance_g;
105 //---------------------------------------------------------------------------
106 // local function prototypes
107 //---------------------------------------------------------------------------
109 static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
111 static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p);
113 static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
115 //=========================================================================//
117 // P U B L I C F U N C T I O N S //
119 //=========================================================================//
121 //---------------------------------------------------------------------------
123 // Function: EplNmtCnuInit
125 // Description: init the first instance of the module
129 // Parameters: uiNodeId_p = NodeId of the local node
132 // Returns: tEplKernel = errorcode
137 //---------------------------------------------------------------------------
138 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
142 Ret = EplNmtCnuAddInstance(uiNodeId_p);
147 //---------------------------------------------------------------------------
149 // Function: EplNmtCnuAddInstance
151 // Description: init the add new instance of the module
155 // Parameters: uiNodeId_p = NodeId of the local node
158 // Returns: tEplKernel = errorcode
163 //---------------------------------------------------------------------------
164 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
168 Ret = kEplSuccessful;
170 // reset instance structure
171 EPL_MEMSET(&EplNmtCnuInstance_g, 0, sizeof(EplNmtCnuInstance_g));
174 EplNmtCnuInstance_g.m_uiNodeId = uiNodeId_p;
176 // register callback-function for NMT-commands
177 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
178 Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
180 kEplDllAsndFilterLocal);
187 //---------------------------------------------------------------------------
189 // Function: EplNmtCnuDelInstance
191 // Description: delte instance of the module
198 // Returns: tEplKernel = errorcode
203 //---------------------------------------------------------------------------
204 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
208 Ret = kEplSuccessful;
210 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
211 // deregister callback function from DLL
212 Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
213 NULL, kEplDllAsndFilterNone);
219 //---------------------------------------------------------------------------
221 // Function: EplNmtCnuSendNmtRequest
223 // Description: Send an NMT-Request to the MN
227 // Parameters: uiNodeId_p = NodeId of the local node
228 // NmtCommand_p = requested NMT-Command
231 // Returns: tEplKernel = errorcode
236 //---------------------------------------------------------------------------
237 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
242 tEplFrameInfo NmtRequestFrameInfo;
243 tEplFrame NmtRequestFrame;
245 Ret = kEplSuccessful;
248 EPL_MEMSET(&NmtRequestFrame.m_be_abDstMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abDstMac)); // set by DLL
249 EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac)); // set by DLL
250 AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType,
251 EPL_C_DLL_ETHERTYPE_EPL);
252 AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (BYTE) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
253 AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType,
254 (BYTE) kEplMsgTypeAsnd);
255 AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId,
256 (BYTE) kEplDllAsndNmtRequest);
257 AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.
258 m_NmtRequestService.m_le_bNmtCommandId,
259 (BYTE) NmtCommand_p);
260 AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (BYTE) uiNodeId_p); // target for the nmt command
261 EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.
262 m_le_abNmtCommandData[0], 0x00,
263 sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload.
264 m_NmtRequestService.m_le_abNmtCommandData));
266 // build info-structure
267 NmtRequestFrameInfo.m_NetTime.m_dwNanoSec = 0;
268 NmtRequestFrameInfo.m_NetTime.m_dwSec = 0;
269 NmtRequestFrameInfo.m_pFrame = &NmtRequestFrame;
270 NmtRequestFrameInfo.m_uiFrameSize = EPL_C_DLL_MINSIZE_NMTREQ; // sizeof(NmtRequestFrame);
273 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
274 Ret = EplDlluCalAsyncSend(&NmtRequestFrameInfo, // pointer to frameinfo
275 kEplDllAsyncReqPrioNmt); // priority
281 //---------------------------------------------------------------------------
283 // Function: EplNmtCnuRegisterStateChangeCb
285 // Description: register Callback-function go get informed about a
286 // NMT-Change-State-Event
290 // Parameters: pfnEplNmtStateChangeCb_p = functionpointer
293 // Returns: tEplKernel = errorcode
298 //---------------------------------------------------------------------------
300 EPLDLLEXPORT tEplKernel PUBLIC
301 EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
302 pfnEplNmtCheckEventCb_p)
306 Ret = kEplSuccessful;
308 // save callback-function in modul global var
309 EplNmtCnuInstance_g.m_pfnCheckEventCb = pfnEplNmtCheckEventCb_p;
315 //=========================================================================//
317 // P R I V A T E F U N C T I O N S //
319 //=========================================================================//
321 //---------------------------------------------------------------------------
323 // Function: EplNmtCnuCommandCb
325 // Description: callback funktion for NMT-Commands
329 // Parameters: pFrameInfo_p = Frame with the NMT-Commando
332 // Returns: tEplKernel = errorcode
337 //---------------------------------------------------------------------------
338 static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p)
340 tEplKernel Ret = kEplSuccessful;
341 tEplNmtCommand NmtCommand;
343 tEplNmtEvent NmtEvent = kEplNmtEventNoEvent;
345 if (pFrameInfo_p == NULL) {
346 Ret = kEplNmtInvalidFramePointer;
350 NmtCommand = EplNmtCnuGetNmtCommand(pFrameInfo_p);
353 switch (NmtCommand) {
355 //------------------------------------------------------------------------
356 // plain NMT state commands
357 case kEplNmtCmdStartNode:
358 { // send NMT-Event to state maschine kEplNmtEventStartNode
359 NmtEvent = kEplNmtEventStartNode;
363 case kEplNmtCmdStopNode:
364 { // send NMT-Event to state maschine kEplNmtEventStopNode
365 NmtEvent = kEplNmtEventStopNode;
369 case kEplNmtCmdEnterPreOperational2:
370 { // send NMT-Event to state maschine kEplNmtEventEnterPreOperational2
371 NmtEvent = kEplNmtEventEnterPreOperational2;
375 case kEplNmtCmdEnableReadyToOperate:
376 { // send NMT-Event to state maschine kEplNmtEventEnableReadyToOperate
377 NmtEvent = kEplNmtEventEnableReadyToOperate;
381 case kEplNmtCmdResetNode:
382 { // send NMT-Event to state maschine kEplNmtEventResetNode
383 NmtEvent = kEplNmtEventResetNode;
387 case kEplNmtCmdResetCommunication:
388 { // send NMT-Event to state maschine kEplNmtEventResetCom
389 NmtEvent = kEplNmtEventResetCom;
393 case kEplNmtCmdResetConfiguration:
394 { // send NMT-Event to state maschine kEplNmtEventResetConfig
395 NmtEvent = kEplNmtEventResetConfig;
399 case kEplNmtCmdSwReset:
400 { // send NMT-Event to state maschine kEplNmtEventSwReset
401 NmtEvent = kEplNmtEventSwReset;
405 //------------------------------------------------------------------------
406 // extended NMT state commands
408 case kEplNmtCmdStartNodeEx:
410 // check if own nodeid is in EPL node list
412 EplNmtCnuNodeIdList(&
413 (pFrameInfo_p->m_pFrame->m_Data.
416 m_le_abNmtCommandData[0]));
417 if (fNodeIdInList != FALSE) { // own nodeid in list
418 // send event to process command
419 NmtEvent = kEplNmtEventStartNode;
424 case kEplNmtCmdStopNodeEx:
425 { // check if own nodeid is in EPL node list
427 EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
430 m_le_abNmtCommandData[0]);
431 if (fNodeIdInList != FALSE) { // 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
441 EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
444 m_le_abNmtCommandData[0]);
445 if (fNodeIdInList != FALSE) { // own nodeid in list
446 // send event to process command
447 NmtEvent = kEplNmtEventEnterPreOperational2;
452 case kEplNmtCmdEnableReadyToOperateEx:
453 { // check if own nodeid is in EPL node list
455 EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
458 m_le_abNmtCommandData[0]);
459 if (fNodeIdInList != FALSE) { // own nodeid in list
460 // send event to process command
461 NmtEvent = kEplNmtEventEnableReadyToOperate;
466 case kEplNmtCmdResetNodeEx:
467 { // check if own nodeid is in EPL node list
469 EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
472 m_le_abNmtCommandData[0]);
473 if (fNodeIdInList != FALSE) { // own nodeid in list
474 // send event to process command
475 NmtEvent = kEplNmtEventResetNode;
480 case kEplNmtCmdResetCommunicationEx:
481 { // check if own nodeid is in EPL node list
483 EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
486 m_le_abNmtCommandData[0]);
487 if (fNodeIdInList != FALSE) { // own nodeid in list
488 // send event to process command
489 NmtEvent = kEplNmtEventResetCom;
494 case kEplNmtCmdResetConfigurationEx:
495 { // check if own nodeid is in EPL node list
497 EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
500 m_le_abNmtCommandData[0]);
501 if (fNodeIdInList != FALSE) { // own nodeid in list
502 // send event to process command
503 NmtEvent = kEplNmtEventResetConfig;
508 case kEplNmtCmdSwResetEx:
509 { // check if own nodeid is in EPL node list
511 EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
514 m_le_abNmtCommandData[0]);
515 if (fNodeIdInList != FALSE) { // own nodeid in list
516 // send event to process command
517 NmtEvent = kEplNmtEventSwReset;
522 //------------------------------------------------------------------------
523 // NMT managing commands
525 // TODO: add functions to process managing command (optional)
527 case kEplNmtCmdNetHostNameSet:
532 case kEplNmtCmdFlushArpEntry:
537 //------------------------------------------------------------------------
540 // TODO: forward event with infos to the application (optional)
542 case kEplNmtCmdPublishConfiguredCN:
547 case kEplNmtCmdPublishActiveCN:
552 case kEplNmtCmdPublishPreOperational1:
557 case kEplNmtCmdPublishPreOperational2:
562 case kEplNmtCmdPublishReadyToOperate:
567 case kEplNmtCmdPublishOperational:
572 case kEplNmtCmdPublishStopped:
577 case kEplNmtCmdPublishEmergencyNew:
582 case kEplNmtCmdPublishTime:
587 //-----------------------------------------------------------------------
589 // -> requested command not supported by MN
590 case kEplNmtCmdInvalidService:
593 // TODO: errorevent to application
597 //------------------------------------------------------------------------
601 Ret = kEplNmtUnknownCommand;
605 } // end of switch(NmtCommand)
607 if (NmtEvent != kEplNmtEventNoEvent) {
608 if (EplNmtCnuInstance_g.m_pfnCheckEventCb != NULL) {
609 Ret = EplNmtCnuInstance_g.m_pfnCheckEventCb(NmtEvent);
610 if (Ret == kEplReject) {
611 Ret = kEplSuccessful;
613 } else if (Ret != kEplSuccessful) {
617 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
618 Ret = EplNmtuNmtEvent(NmtEvent);
627 //---------------------------------------------------------------------------
629 // Function: EplNmtCnuGetNmtCommand()
631 // Description: returns the NMT-Command from the frame
635 // Parameters: pFrameInfo_p = pointer to the Frame
636 // with the NMT-Command
639 // Returns: tEplNmtCommand = NMT-Command
644 //---------------------------------------------------------------------------
645 static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p)
647 tEplNmtCommand NmtCommand;
648 tEplNmtCommandService *pNmtCommandService;
651 &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.
655 (tEplNmtCommand) AmiGetByteFromLe(&pNmtCommandService->
661 //---------------------------------------------------------------------------
663 // Function: EplNmtCnuNodeIdList()
665 // Description: check if the own nodeid is set in EPL Node List
669 // Parameters: pbNmtCommandDate_p = pointer to the data of the NMT Command
672 // Returns: BOOL = TRUE if nodeid is set in EPL Node List
673 // FALSE if nodeid not set in EPL Node List
678 //---------------------------------------------------------------------------
679 static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p)
682 unsigned int uiByteOffset;
686 // get byte-offset of the own nodeid in NodeIdList
688 uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3);
690 bBitOffset = (BYTE) EplNmtCnuInstance_g.m_uiNodeId % 8;
692 bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
693 if ((bNodeListByte & bBitOffset) == 0) {
694 fNodeIdInList = FALSE;
696 fNodeIdInList = TRUE;
699 return fNodeIdInList;
702 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)