• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2 
3   (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4       www.systec-electronic.com
5 
6   Project:      openPOWERLINK
7 
8   Description:  source file for SDO/Asnd-Protocolabstractionlayer module
9 
10   License:
11 
12     Redistribution and use in source and binary forms, with or without
13     modification, are permitted provided that the following conditions
14     are met:
15 
16     1. Redistributions of source code must retain the above copyright
17        notice, this list of conditions and the following disclaimer.
18 
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.
22 
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.
27 
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.
40 
41     Severability Clause:
42 
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.
49 
50   -------------------------------------------------------------------------
51 
52                 $RCSfile: EplSdoAsndu.c,v $
53 
54                 $Author: D.Krueger $
55 
56                 $Revision: 1.7 $  $Date: 2008/10/17 15:32:32 $
57 
58                 $State: Exp $
59 
60                 Build Environment:
61                     GCC V3.4
62 
63   -------------------------------------------------------------------------
64 
65   Revision History:
66 
67   2006/07/07 k.t.:   start of the implementation
68 
69 ****************************************************************************/
70 
71 #include "user/EplSdoAsndu.h"
72 #include "user/EplDlluCal.h"
73 
74 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
75 
76 /***************************************************************************/
77 /*                                                                         */
78 /*                                                                         */
79 /*          G L O B A L   D E F I N I T I O N S                            */
80 /*                                                                         */
81 /*                                                                         */
82 /***************************************************************************/
83 
84 //---------------------------------------------------------------------------
85 // const defines
86 //---------------------------------------------------------------------------
87 
88 #ifndef EPL_SDO_MAX_CONNECTION_ASND
89 #define EPL_SDO_MAX_CONNECTION_ASND 5
90 #endif
91 
92 //---------------------------------------------------------------------------
93 // local types
94 //---------------------------------------------------------------------------
95 
96 // instance table
97 typedef struct {
98 	unsigned int m_auiSdoAsndConnection[EPL_SDO_MAX_CONNECTION_ASND];
99 	tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
100 
101 } tEplSdoAsndInstance;
102 
103 //---------------------------------------------------------------------------
104 // modul globale vars
105 //---------------------------------------------------------------------------
106 
107 static tEplSdoAsndInstance SdoAsndInstance_g;
108 
109 //---------------------------------------------------------------------------
110 // local function prototypes
111 //---------------------------------------------------------------------------
112 
113 tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
114 
115 /***************************************************************************/
116 /*                                                                         */
117 /*                                                                         */
118 /*          C L A S S  <EPL SDO-Asnd Protocolabstraction layer>            */
119 /*                                                                         */
120 /*                                                                         */
121 /***************************************************************************/
122 //
123 // Description: EPL SDO-Asnd Protocolabstraction layer
124 //
125 //
126 /***************************************************************************/
127 
128 //=========================================================================//
129 //                                                                         //
130 //          P U B L I C   F U N C T I O N S                                //
131 //                                                                         //
132 //=========================================================================//
133 
134 //---------------------------------------------------------------------------
135 //
136 // Function:    EplSdoAsnduInit
137 //
138 // Description: init first instance of the module
139 //
140 //
141 //
142 // Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
143 //                                  callback-function
144 //
145 //
146 // Returns:     tEplKernel  = Errorcode
147 //
148 //
149 // State:
150 //
151 //---------------------------------------------------------------------------
EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)152 tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
153 {
154 	tEplKernel Ret;
155 
156 	Ret = EplSdoAsnduAddInstance(fpReceiveCb_p);
157 
158 	return Ret;
159 }
160 
161 //---------------------------------------------------------------------------
162 //
163 // Function:    EplSdoAsnduAddInstance
164 //
165 // Description: init additional instance of the module
166 //
167 //
168 //
169 // Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
170 //                                  callback-function
171 //
172 //
173 // Returns:     tEplKernel  = Errorcode
174 //
175 //
176 // State:
177 //
178 //---------------------------------------------------------------------------
EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)179 tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
180 {
181 	tEplKernel Ret;
182 
183 	Ret = kEplSuccessful;
184 
185 	// init control structure
186 	EPL_MEMSET(&SdoAsndInstance_g, 0x00, sizeof(SdoAsndInstance_g));
187 
188 	// save pointer to callback-function
189 	if (fpReceiveCb_p != NULL) {
190 		SdoAsndInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
191 	} else {
192 		Ret = kEplSdoUdpMissCb;
193 	}
194 
195 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
196 	Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
197 				       EplSdoAsnduCb, kEplDllAsndFilterLocal);
198 #endif
199 
200 	return Ret;
201 }
202 
203 //---------------------------------------------------------------------------
204 //
205 // Function:    EplSdoAsnduDelInstance
206 //
207 // Description: del instance of the module
208 //              del socket and del Listen-Thread
209 //
210 //
211 //
212 // Parameters:
213 //
214 //
215 // Returns:     tEplKernel  = Errorcode
216 //
217 //
218 // State:
219 //
220 //---------------------------------------------------------------------------
EplSdoAsnduDelInstance()221 tEplKernel PUBLIC EplSdoAsnduDelInstance()
222 {
223 	tEplKernel Ret;
224 
225 	Ret = kEplSuccessful;
226 
227 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
228 	// deregister callback function from DLL
229 	Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
230 				       NULL, kEplDllAsndFilterNone);
231 #endif
232 
233 	return Ret;
234 }
235 
236 //---------------------------------------------------------------------------
237 //
238 // Function:    EplSdoAsnduInitCon
239 //
240 // Description: init a new connect
241 //
242 //
243 //
244 // Parameters:  pSdoConHandle_p = pointer for the new connection handle
245 //              uiTargetNodeId_p = NodeId of the target node
246 //
247 //
248 // Returns:     tEplKernel  = Errorcode
249 //
250 //
251 // State:
252 //
253 //---------------------------------------------------------------------------
EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,unsigned int uiTargetNodeId_p)254 tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
255 				     unsigned int uiTargetNodeId_p)
256 {
257 	tEplKernel Ret;
258 	unsigned int uiCount;
259 	unsigned int uiFreeCon;
260 	unsigned int *puiConnection;
261 
262 	Ret = kEplSuccessful;
263 
264 	if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
265 	    || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) {
266 		Ret = kEplSdoAsndInvalidNodeId;
267 		goto Exit;
268 	}
269 	// get free entry in control structure
270 	uiCount = 0;
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);
277 
278 			goto Exit;
279 		} else if (*puiConnection == 0) {	// free entry-> save target nodeId
280 			uiFreeCon = uiCount;
281 		}
282 		uiCount++;
283 		puiConnection++;
284 	}
285 
286 	if (uiFreeCon == EPL_SDO_MAX_CONNECTION_ASND) {
287 		// no free connection
288 		Ret = kEplSdoAsndNoFreeHandle;
289 	} else {
290 		puiConnection =
291 		    &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeCon];
292 		*puiConnection = uiTargetNodeId_p;
293 		// save handle for higher layer
294 		*pSdoConHandle_p = (uiFreeCon | EPL_SDO_ASND_HANDLE);
295 
296 		goto Exit;
297 	}
298 
299       Exit:
300 	return Ret;
301 }
302 
303 //---------------------------------------------------------------------------
304 //
305 // Function:    EplSdoAsnduSendData
306 //
307 // Description: send data using exisiting connection
308 //
309 //
310 //
311 // Parameters:  SdoConHandle_p  = connection handle
312 //              pSrcData_p      = pointer to data
313 //              dwDataSize_p    = number of databyte
314 //                                  -> without asnd-header!!!
315 //
316 // Returns:     tEplKernel  = Errorcode
317 //
318 //
319 // State:
320 //
321 //---------------------------------------------------------------------------
EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,tEplFrame * pSrcData_p,DWORD dwDataSize_p)322 tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
323 				      tEplFrame * pSrcData_p,
324 				      DWORD dwDataSize_p)
325 {
326 	tEplKernel Ret;
327 	unsigned int uiArray;
328 	tEplFrameInfo FrameInfo;
329 
330 	Ret = kEplSuccessful;
331 
332 	uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
333 
334 	if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) {
335 		Ret = kEplSdoAsndInvalidHandle;
336 		goto Exit;
337 	}
338 	// fillout Asnd header
339 	// own node id not needed -> filled by DLL
340 
341 	// set message type
342 	AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (BYTE) kEplMsgTypeAsnd);	// ASnd == 0x06
343 	// target node id
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);
349 
350 	// calc size
351 	dwDataSize_p += EPL_ASND_HEADER_SIZE;
352 
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);
359 #endif
360 
361       Exit:
362 	return Ret;
363 
364 }
365 
366 //---------------------------------------------------------------------------
367 //
368 // Function:    EplSdoAsnduDelCon
369 //
370 // Description: delete connection from intern structure
371 //
372 //
373 //
374 // Parameters:  SdoConHandle_p  = connection handle
375 //
376 // Returns:     tEplKernel  = Errorcode
377 //
378 //
379 // State:
380 //
381 //---------------------------------------------------------------------------
EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)382 tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
383 {
384 	tEplKernel Ret;
385 	unsigned int uiArray;
386 
387 	Ret = kEplSuccessful;
388 
389 	uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
390 	// check parameter
391 	if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) {
392 		Ret = kEplSdoAsndInvalidHandle;
393 		goto Exit;
394 	}
395 	// set target nodeId to 0
396 	SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray] = 0;
397 
398       Exit:
399 	return Ret;
400 }
401 
402 //=========================================================================//
403 //                                                                         //
404 //          P R I V A T E   F U N C T I O N S                              //
405 //                                                                         //
406 //=========================================================================//
407 
408 //---------------------------------------------------------------------------
409 //
410 // Function:    EplSdoAsnduCb
411 //
412 // Description: callback function for SDO ASnd frames
413 //
414 //
415 //
416 // Parameters:      pFrameInfo_p = Frame with SDO payload
417 //
418 //
419 // Returns:         tEplKernel = errorcode
420 //
421 //
422 // State:
423 //
424 //---------------------------------------------------------------------------
EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)425 tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)
426 {
427 	tEplKernel Ret = kEplSuccessful;
428 	unsigned int uiCount;
429 	unsigned int *puiConnection;
430 	unsigned int uiNodeId;
431 	unsigned int uiFreeEntry = 0xFFFF;
432 	tEplSdoConHdl SdoConHdl;
433 	tEplFrame *pFrame;
434 
435 	pFrame = pFrameInfo_p->m_pFrame;
436 
437 	uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
438 
439 	// search corresponding entry in control structure
440 	uiCount = 0;
441 	puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
442 	while (uiCount < EPL_SDO_MAX_CONNECTION_ASND) {
443 		if (uiNodeId == *puiConnection) {
444 			break;
445 		} else if ((*puiConnection == 0)
446 			   && (uiFreeEntry == 0xFFFF)) {	// free entry
447 			uiFreeEntry = uiCount;
448 		}
449 		uiCount++;
450 		puiConnection++;
451 	}
452 
453 	if (uiCount == EPL_SDO_MAX_CONNECTION_ASND) {
454 		if (uiFreeEntry != 0xFFFF) {
455 			puiConnection =
456 			    &SdoAsndInstance_g.
457 			    m_auiSdoAsndConnection[uiFreeEntry];
458 			*puiConnection = uiNodeId;
459 			uiCount = uiFreeEntry;
460 		} else {
461 			EPL_DBGLVL_SDO_TRACE0
462 			    ("EplSdoAsnduCb(): no free handle\n");
463 			goto Exit;
464 		}
465 	}
466 //    if (uiNodeId == *puiConnection)
467 	{			// entry found or created
468 		SdoConHdl = (uiCount | EPL_SDO_ASND_HANDLE);
469 
470 		SdoAsndInstance_g.m_fpSdoAsySeqCb(SdoConHdl,
471 						  &pFrame->m_Data.m_Asnd.
472 						  m_Payload.m_SdoSequenceFrame,
473 						  (pFrameInfo_p->m_uiFrameSize -
474 						   18));
475 	}
476 
477       Exit:
478 	return Ret;
479 
480 }
481 
482 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
483 // EOF
484