1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for SDO/Asnd-Protocolabstractionlayer 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: EplSdoAsndu.c,v $
56 $Revision: 1.7 $ $Date: 2008/10/17 15:32:32 $
63 -------------------------------------------------------------------------
67 2006/07/07 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "user/EplSdoAsndu.h"
72 #include "user/EplDlluCal.h"
74 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
76 /***************************************************************************/
79 /* G L O B A L D E F I N I T I O N S */
82 /***************************************************************************/
84 //---------------------------------------------------------------------------
86 //---------------------------------------------------------------------------
88 #ifndef EPL_SDO_MAX_CONNECTION_ASND
89 #define EPL_SDO_MAX_CONNECTION_ASND 5
92 //---------------------------------------------------------------------------
94 //---------------------------------------------------------------------------
98 unsigned int m_auiSdoAsndConnection[EPL_SDO_MAX_CONNECTION_ASND];
99 tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
101 } tEplSdoAsndInstance;
103 //---------------------------------------------------------------------------
104 // modul globale vars
105 //---------------------------------------------------------------------------
107 static tEplSdoAsndInstance SdoAsndInstance_g;
109 //---------------------------------------------------------------------------
110 // local function prototypes
111 //---------------------------------------------------------------------------
113 tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
115 /***************************************************************************/
118 /* C L A S S <EPL SDO-Asnd Protocolabstraction layer> */
121 /***************************************************************************/
123 // Description: EPL SDO-Asnd Protocolabstraction layer
126 /***************************************************************************/
128 //=========================================================================//
130 // P U B L I C F U N C T I O N S //
132 //=========================================================================//
134 //---------------------------------------------------------------------------
136 // Function: EplSdoAsnduInit
138 // Description: init first instance of the module
142 // Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
146 // Returns: tEplKernel = Errorcode
151 //---------------------------------------------------------------------------
152 tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
156 Ret = EplSdoAsnduAddInstance(fpReceiveCb_p);
161 //---------------------------------------------------------------------------
163 // Function: EplSdoAsnduAddInstance
165 // Description: init additional instance of the module
169 // Parameters: pReceiveCb_p = functionpointer to Sdo-Sequence layer
173 // Returns: tEplKernel = Errorcode
178 //---------------------------------------------------------------------------
179 tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
183 Ret = kEplSuccessful;
185 // init control structure
186 EPL_MEMSET(&SdoAsndInstance_g, 0x00, sizeof(SdoAsndInstance_g));
188 // save pointer to callback-function
189 if (fpReceiveCb_p != NULL) {
190 SdoAsndInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
192 Ret = kEplSdoUdpMissCb;
195 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
196 Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
197 EplSdoAsnduCb, kEplDllAsndFilterLocal);
203 //---------------------------------------------------------------------------
205 // Function: EplSdoAsnduDelInstance
207 // Description: del instance of the module
208 // del socket and del Listen-Thread
215 // Returns: tEplKernel = Errorcode
220 //---------------------------------------------------------------------------
221 tEplKernel PUBLIC EplSdoAsnduDelInstance()
225 Ret = kEplSuccessful;
227 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
228 // deregister callback function from DLL
229 Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
230 NULL, kEplDllAsndFilterNone);
236 //---------------------------------------------------------------------------
238 // Function: EplSdoAsnduInitCon
240 // Description: init a new connect
244 // Parameters: pSdoConHandle_p = pointer for the new connection handle
245 // uiTargetNodeId_p = NodeId of the target node
248 // Returns: tEplKernel = Errorcode
253 //---------------------------------------------------------------------------
254 tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
255 unsigned int uiTargetNodeId_p)
258 unsigned int uiCount;
259 unsigned int uiFreeCon;
260 unsigned int *puiConnection;
262 Ret = kEplSuccessful;
264 if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
265 || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) {
266 Ret = kEplSdoAsndInvalidNodeId;
269 // get free entry in control structure
271 uiFreeCon = EPL_SDO_MAX_CONNECTION_ASND;
272 puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
273 while (uiCount < EPL_SDO_MAX_CONNECTION_ASND) {
274 if (*puiConnection == uiTargetNodeId_p) { // existing connection to target node found
275 // save handle for higher layer
276 *pSdoConHandle_p = (uiCount | EPL_SDO_ASND_HANDLE);
279 } else if (*puiConnection == 0) { // free entry-> save target nodeId
286 if (uiFreeCon == EPL_SDO_MAX_CONNECTION_ASND) {
287 // no free connection
288 Ret = kEplSdoAsndNoFreeHandle;
291 &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeCon];
292 *puiConnection = uiTargetNodeId_p;
293 // save handle for higher layer
294 *pSdoConHandle_p = (uiFreeCon | EPL_SDO_ASND_HANDLE);
303 //---------------------------------------------------------------------------
305 // Function: EplSdoAsnduSendData
307 // Description: send data using exisiting connection
311 // Parameters: SdoConHandle_p = connection handle
312 // pSrcData_p = pointer to data
313 // dwDataSize_p = number of databyte
314 // -> without asnd-header!!!
316 // Returns: tEplKernel = Errorcode
321 //---------------------------------------------------------------------------
322 tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
323 tEplFrame * pSrcData_p,
327 unsigned int uiArray;
328 tEplFrameInfo FrameInfo;
330 Ret = kEplSuccessful;
332 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
334 if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) {
335 Ret = kEplSdoAsndInvalidHandle;
338 // fillout Asnd header
339 // own node id not needed -> filled by DLL
342 AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (BYTE) kEplMsgTypeAsnd); // ASnd == 0x06
344 AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId,
345 (BYTE) SdoAsndInstance_g.
346 m_auiSdoAsndConnection[uiArray]);
347 // set source-nodeid (filled by DLL 0)
348 AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
351 dwDataSize_p += EPL_ASND_HEADER_SIZE;
353 // send function of DLL
354 FrameInfo.m_uiFrameSize = dwDataSize_p;
355 FrameInfo.m_pFrame = pSrcData_p;
356 EPL_MEMSET(&FrameInfo.m_NetTime, 0x00, sizeof(tEplNetTime));
357 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
358 Ret = EplDlluCalAsyncSend(&FrameInfo, kEplDllAsyncReqPrioGeneric);
366 //---------------------------------------------------------------------------
368 // Function: EplSdoAsnduDelCon
370 // Description: delete connection from intern structure
374 // Parameters: SdoConHandle_p = connection handle
376 // Returns: tEplKernel = Errorcode
381 //---------------------------------------------------------------------------
382 tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
385 unsigned int uiArray;
387 Ret = kEplSuccessful;
389 uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
391 if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) {
392 Ret = kEplSdoAsndInvalidHandle;
395 // set target nodeId to 0
396 SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray] = 0;
402 //=========================================================================//
404 // P R I V A T E F U N C T I O N S //
406 //=========================================================================//
408 //---------------------------------------------------------------------------
410 // Function: EplSdoAsnduCb
412 // Description: callback function for SDO ASnd frames
416 // Parameters: pFrameInfo_p = Frame with SDO payload
419 // Returns: tEplKernel = errorcode
424 //---------------------------------------------------------------------------
425 tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)
427 tEplKernel Ret = kEplSuccessful;
428 unsigned int uiCount;
429 unsigned int *puiConnection;
430 unsigned int uiNodeId;
431 unsigned int uiFreeEntry = 0xFFFF;
432 tEplSdoConHdl SdoConHdl;
435 pFrame = pFrameInfo_p->m_pFrame;
437 uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
439 // search corresponding entry in control structure
441 puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
442 while (uiCount < EPL_SDO_MAX_CONNECTION_ASND) {
443 if (uiNodeId == *puiConnection) {
445 } else if ((*puiConnection == 0)
446 && (uiFreeEntry == 0xFFFF)) { // free entry
447 uiFreeEntry = uiCount;
453 if (uiCount == EPL_SDO_MAX_CONNECTION_ASND) {
454 if (uiFreeEntry != 0xFFFF) {
457 m_auiSdoAsndConnection[uiFreeEntry];
458 *puiConnection = uiNodeId;
459 uiCount = uiFreeEntry;
461 EPL_DBGLVL_SDO_TRACE0
462 ("EplSdoAsnduCb(): no free handle\n");
466 // if (uiNodeId == *puiConnection)
467 { // entry found or created
468 SdoConHdl = (uiCount | EPL_SDO_ASND_HANDLE);
470 SdoAsndInstance_g.m_fpSdoAsySeqCb(SdoConHdl,
471 &pFrame->m_Data.m_Asnd.
472 m_Payload.m_SdoSequenceFrame,
473 (pFrameInfo_p->m_uiFrameSize -
482 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)