2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
6 See COPYING file for copyrights details.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* #define DEBUG_WAR_CONSOLE_ON */
24 /* #define DEBUG_ERR_CONSOLE_ON */
29 /* Uncomment if your compiler does not support inline functions */
38 /*Internals prototypes*/
40 /** Called by writeNetworkDict */
41 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
42 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback);
44 /** Called by readNetworkDict */
45 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex,
46 UNS8 dataType, SDOCallback_t Callback);
49 /***************************************************************************/
50 /* SDO (un)packing macros */
52 /** Returns the command specifier (cs, ccs, scs) from the first byte of the SDO
54 #define getSDOcs(byte) (byte >> 5)
56 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 2 bits
58 #define getSDOn2(byte) ((byte >> 2) & 3)
60 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 3 bits
62 #define getSDOn3(byte) ((byte >> 1) & 7)
64 /** Returns the transfer type from the first byte of the SDO
66 #define getSDOe(byte) ((byte >> 1) & 1)
68 /** Returns the size indicator from the first byte of the SDO
70 #define getSDOs(byte) (byte & 1)
72 /** Returns the indicator of end transmission from the first byte of the SDO
74 #define getSDOc(byte) (byte & 1)
76 /** Returns the toggle from the first byte of the SDO
78 #define getSDOt(byte) ((byte >> 4) & 1)
80 /** Returns the index from the bytes 1 and 2 of the SDO
82 #define getSDOindex(byte1, byte2) ((byte2 << 8) | (byte1))
84 /** Returns the subIndex from the byte 3 of the SDO
87 #define getSDOsubIndex(byte3) (byte3)
89 /***************************************************************************
92 void SDOTimeoutAlarm(CO_Data* d, UNS32 id)
94 MSG_ERR(0x1A01, "SDO timeout. SDO response not received.", 0);
95 MSG_WAR(0x2A02, "server node : ", d->transfers[id].nodeId);
96 MSG_WAR(0x2A02, " index : ", d->transfers[id].index);
97 MSG_WAR(0x2A02, " subIndex : ", d->transfers[id].subIndex);
98 /* Reset timer handler */
99 d->transfers[id].timer = TIMER_NONE;
100 /* Call the user function to inform of the problem.*/
101 (*d->SDOtimeoutError)(id);
102 /* Sending a SDO abort */
103 sendSDOabort(d, d->transfers[id].whoami,
104 d->transfers[id].index, d->transfers[id].subIndex, SDOABT_TIMED_OUT);
109 #define StopSDO_TIMER(id) \
110 MSG_WAR(0x3A05, "StopSDO_TIMER for line : ", line);\
111 d->transfers[id].timer = DelAlarm(d->transfers[id].timer);
113 #define StartSDO_TIMER(id) \
114 MSG_WAR(0x3A06, "StartSDO_TIMER for line : ", line);\
115 d->transfers[id].timer = SetAlarm(d,id,&SDOTimeoutAlarm,MS_TO_TIMEVAL(SDO_TIMEOUT_MS),0);
117 #define RestartSDO_TIMER(id) \
118 MSG_WAR(0x3A07, "restartSDO_TIMER for line : ", line);\
119 if(d->transfers[id].timer != TIMER_NONE) { StopSDO_TIMER(id) StartSDO_TIMER(id) }
121 /***************************************************************************/
122 /** Reset all sdo buffers
124 void resetSDO (CO_Data* d)
128 /* transfer structure initialization */
129 for (j = 0 ; j < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; j++)
133 /***************************************************************************/
134 UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line)
138 MSG_WAR(0x3A08, "Enter in SDOlineToObjdict ", line);
139 size = d->transfers[line].count;
140 errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
141 (void *) d->transfers[line].data, &size, 1);
142 if (errorCode != OD_SUCCESSFUL)
144 MSG_WAR(0x3A08, "exit of SDOlineToObjdict ", line);
149 /***************************************************************************/
150 UNS32 objdictToSDOline (CO_Data* d, UNS8 line)
156 MSG_WAR(0x3A05, "objdict->line index : ", d->transfers[line].index);
157 MSG_WAR(0x3A06, " subIndex : ", d->transfers[line].subIndex);
159 errorCode = getODentry(d, d->transfers[line].index,
160 d->transfers[line].subIndex,
161 (void *)d->transfers[line].data,
162 &size, &dataType, 0);
164 if (errorCode != OD_SUCCESSFUL)
167 d->transfers[line].count = size;
168 d->transfers[line].offset = 0;
170 /*Me laisser ça, please ! (FD)*/
173 for (i = 0 ; i < 10 ; i++) {
174 MSG_WAR(i, "data= ", d->transfers[line].data[i]);
181 /***************************************************************************/
182 UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data) {
186 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
187 MSG_ERR(0x1A10,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
190 if ((d->transfers[line].offset + nbBytes) > d->transfers[line].count) {
191 MSG_ERR(0x1A11,"SDO Size of data too large. Exceed count", nbBytes);
194 offset = d->transfers[line].offset;
195 for (i = 0 ; i < nbBytes ; i++)
196 * (data + i) = d->transfers[line].data[offset + i];
197 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
202 /***************************************************************************/
203 UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data)
208 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
209 MSG_ERR(0x1A15,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
212 offset = d->transfers[line].offset;
213 for (i = 0 ; i < nbBytes ; i++)
214 d->transfers[line].data[offset + i] = * (data + i);
215 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
219 /***************************************************************************/
220 UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index,
221 UNS8 subIndex, UNS32 abortCode)
225 err = getSDOlineOnUse( d, nodeId, whoami, &line );
226 if (!err) /* If a line on use have been found.*/
227 MSG_WAR(0x3A20, "FailedSDO : line found : ", line);
228 if ((! err) && (whoami == SDO_SERVER)) {
229 resetSDOline( d, line );
230 MSG_WAR(0x3A21, "FailedSDO : line released : ", line);
232 if ((! err) && (whoami == SDO_CLIENT)) {
234 d->transfers[line].state = SDO_ABORTED_INTERNAL;
236 MSG_WAR(0x3A22, "Sending SDO abort ", 0);
237 err = sendSDOabort(d, whoami, index, subIndex, abortCode);
239 MSG_WAR(0x3A23, "Unable to send the SDO abort", 0);
245 /***************************************************************************/
246 void resetSDOline ( CO_Data* d, UNS8 line )
249 MSG_WAR(0x3A25, "reset SDO line nb : ", line);
250 initSDOline(d, line, 0, 0, 0, SDO_RESET);
251 for (i = 0 ; i < SDO_MAX_LENGTH_TRANSFERT ; i++)
252 d->transfers[line].data[i] = 0;
255 /***************************************************************************/
256 UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state)
258 MSG_WAR(0x3A25, "init SDO line nb : ", line);
259 if (state == SDO_DOWNLOAD_IN_PROGRESS || state == SDO_UPLOAD_IN_PROGRESS){
264 d->transfers[line].nodeId = nodeId;
265 d->transfers[line].index = index;
266 d->transfers[line].subIndex = subIndex;
267 d->transfers[line].state = state;
268 d->transfers[line].toggle = 0;
269 d->transfers[line].count = 0;
270 d->transfers[line].offset = 0;
271 d->transfers[line].dataType = 0;
272 d->transfers[line].Callback = NULL;
276 /***************************************************************************/
277 UNS8 getSDOfreeLine ( CO_Data* d, UNS8 whoami, UNS8 *line )
282 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
283 if ( d->transfers[i].state == SDO_RESET ) {
285 d->transfers[i].whoami = whoami;
289 MSG_ERR(0x1A25, "Too many SDO in progress. Aborted.", i);
293 /***************************************************************************/
294 UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line)
299 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
300 if ( (d->transfers[i].state != SDO_RESET) &&
301 (d->transfers[i].nodeId == nodeId) &&
302 (d->transfers[i].whoami == whoami) ) {
310 /***************************************************************************/
311 UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami)
315 err = getSDOlineOnUse(d, nodeId, whoami, &line);
317 MSG_WAR(0x2A30, "No SDO communication to close for node : ", nodeId);
320 resetSDOline(d, line);
324 /***************************************************************************/
325 UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 * nbBytes)
327 if (d->transfers[line].count == 0) /* if received initiate SDO protocol with e=0 and s=0 */
330 * nbBytes = d->transfers[line].count - d->transfers[line].offset;
334 /***************************************************************************/
335 UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 nbBytes)
337 if (nbBytes > SDO_MAX_LENGTH_TRANSFERT) {
338 MSG_ERR(0x1A35,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
341 d->transfers[line].count = nbBytes;
346 /***************************************************************************/
347 UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo)
354 UNS32 * pwCobId = NULL;
355 UNS8 * pwNodeId = NULL;
357 MSG_WAR(0x3A38, "sendSDO",0);
358 if( !((d->nodeState == Operational) || (d->nodeState == Pre_operational ))) {
359 MSG_WAR(0x2A39, "unable to send the SDO (not in op or pre-op mode", d->nodeState);
363 /*get the server->client cobid*/
364 if ( whoami == SDO_SERVER ) {/*case server. Easy because today only one server SDO is authorized in CanFestival*/
365 offset = d->firstIndex->SDO_SVR;
367 MSG_ERR(0x1A42, "SendSDO : No SDO server found", 0);
370 pwCobId = d->objdict[offset].pSubindex[2].pObject;
371 MSG_WAR(0x3A41, "I am server. cobId : ", *pwCobId);
373 else { /*case client*/
374 /* Get the client->server cobid.*/
376 offset = d->firstIndex->SDO_CLT;
377 lastIndex = d->lastIndex->SDO_CLT;
379 MSG_ERR(0x1A42, "SendSDO : No SDO client index found", 0);
382 /* First, have to find at the index where is defined the communication with the server node */
383 while (offset <= lastIndex){
384 MSG_WAR(0x3A43,"Reading index : ", 0x1280 + sdoNum);
385 if (d->objdict[offset].bSubCount <= 3) {
386 MSG_ERR(0x1A28, "Subindex 3 not found at index ", 0x1280 + sdoNum);
389 pwNodeId = d->objdict[offset].pSubindex[3].pObject;
390 MSG_WAR(0x3A44, "Found nodeId server = ", *pwNodeId);
391 if(*pwNodeId == sdo.nodeId) {
399 MSG_WAR (0x2A45, "No SDO client corresponds to the mesage to send to node ", sdo.nodeId);
402 /* Second, read the cobid client->server */
403 pwCobId = d->objdict[offset].pSubindex[1].pObject;
405 /* message copy for sending */
406 m.cob_id.w = *pwCobId;
407 m.rtr = NOT_A_REQUEST;
408 /* the length of SDO must be 8 */
410 for (i = 0 ; i < 8 ; i++) {
411 m.data[i] = sdo.body.data[i];
413 return (*d->canSend)(&m);
416 /***************************************************************************/
417 UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS16 index, UNS8 subIndex, UNS32 abortCode)
421 MSG_WAR(0x2A50,"Sending SDO abort ", abortCode);
422 sdo.nodeId = *d->bDeviceNodeId;
423 sdo.body.data[0] = 0x80;
425 sdo.body.data[1] = index & 0xFF; /* LSB */
426 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
428 sdo.body.data[3] = subIndex;
430 sdo.body.data[4] = (UNS8)(abortCode & 0xFF);
431 sdo.body.data[5] = (UNS8)((abortCode >> 8) & 0xFF);
432 sdo.body.data[6] = (UNS8)((abortCode >> 16) & 0xFF);
433 sdo.body.data[7] = (UNS8)((abortCode >> 24) & 0xFF);
434 ret = sendSDO(d, whoami, sdo);
439 /***************************************************************************/
440 UNS8 proceedSDO (CO_Data* d, Message *m)
444 UNS8 nbBytes; /* received or to be transmited. */
445 UNS8 nodeId = 0; /* The node from which the SDO is received */
446 UNS8 *pNodeId = NULL;
447 UNS8 whoami = SDO_UNKNOWN; /* SDO_SERVER or SDO_CLIENT.*/
448 UNS32 errorCode; /* while reading or writing in the local object dictionary.*/
449 s_SDO sdo; /* SDO to transmit */
454 UNS32 * pCobId = NULL;
458 MSG_WAR(0x3A60, "proceedSDO ", 0);
459 whoami = SDO_UNKNOWN;
460 /* Looking for the cobId in the object dictionary. */
461 /* Am-I a server ? */
462 offset = d->firstIndex->SDO_SVR;
463 lastIndex = d->lastIndex->SDO_SVR;
465 if(offset) while (offset <= lastIndex) {
466 if (d->objdict[offset].bSubCount <= 1) {
467 MSG_ERR(0x1A61, "Subindex 1 not found at index ", 0x1200 + j);
470 pCobId = d->objdict[offset].pSubindex[1].pObject;
471 if ( *pCobId == (*m).cob_id.w ) {
473 MSG_WAR(0x3A62, "proceedSDO. I am server. index : ", 0x1200 + j);
474 /* In case of server, the node id of the client may be unknown. So we put the index minus offset */
475 /* 0x1200 where the cobid received is defined. */
482 if (whoami == SDO_UNKNOWN) {
484 offset = d->firstIndex->SDO_CLT;
485 lastIndex = d->lastIndex->SDO_CLT;
487 if(offset) while (offset <= lastIndex) {
488 if (d->objdict[offset].bSubCount <= 3) {
489 MSG_ERR(0x1A63, "Subindex 3 not found at index ", 0x1280 + j);
492 /* a) Looking for the cobid received. */
493 pCobId = d->objdict[offset].pSubindex[2].pObject;
494 if (*pCobId == (*m).cob_id.w ) {
495 /* b) cobid found, so reading the node id of the server. */
496 pNodeId = d->objdict[offset].pSubindex[3].pObject;
499 MSG_WAR(0x3A64, "proceedSDO. I am server. index : ", 0x1280 + j);
500 MSG_WAR(0x3A65, " Server nodeId : ", nodeId);
507 if (whoami == SDO_UNKNOWN) {
508 return 0xFF;/* This SDO was not for us ! */
511 /* Test if the size of the SDO is ok */
512 if ( (*m).len != 8) {
513 MSG_ERR(0x1A67, "Error size SDO. CobId : ", (*m).cob_id.w);
514 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_GENERAL_ERROR);
518 if (whoami == SDO_CLIENT) {
519 MSG_WAR(0x3A68, "I am CLIENT. Received SDO from nodeId : ", nodeId);
522 MSG_WAR(0x3A69, "I am SERVER. Received SDO cobId : ", (*m).cob_id.w);
525 /* Testing the command specifier */
526 /* Allowed : cs = 0, 1, 2, 3, 4. (= all except those for block tranfert). */
527 /* cs = other : Not allowed -> abort. */
528 switch (getSDOcs(m->data[0])) {
532 if (whoami == SDO_SERVER) {
533 /* Receiving a download segment data. */
534 /* A SDO transfert should have been yet initiated. */
535 err = getSDOlineOnUse( d, nodeId, whoami, &line );
537 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
539 MSG_ERR(0x1A70, "SDO error : Received download segment for unstarted trans. index 0x1200 + ",
541 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
544 /* Reset the wathdog */
545 RestartSDO_TIMER(line)
546 MSG_WAR(0x3A71, "Received SDO download segment defined at index 0x1200 + ", nodeId);
547 index = d->transfers[line].index;
548 subIndex = d->transfers[line].subIndex;
550 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
551 MSG_ERR(0x1A72, "SDO error : Toggle error : ", getSDOt(m->data[0]));
552 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
555 /* Nb of data to be downloaded */
556 nbBytes = 7 - getSDOn3(m->data[0]);
557 /* Store the data in the transfert structure. */
558 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
560 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
563 /* Sending the SDO response, CS = 1 */
564 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender). */
565 sdo.body.data[0] = (1 << 5) | (d->transfers[line].toggle << 4);
566 for (i = 1 ; i < 8 ; i++)
567 sdo.body.data[i] = 0;
568 MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", nodeId);
569 sendSDO(d, whoami, sdo);
570 /* Inverting the toggle for the next segment. */
571 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
572 /* If it was the last segment, */
573 if (getSDOc(m->data[0])) {
574 /* Transfering line data to object dictionary. */
575 /* The code does not use the "d" of initiate frame. So it is safe if e=s=0 */
576 errorCode = SDOlineToObjdict(d, line);
578 MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0);
579 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
582 /* Release of the line */
583 resetSDOline(d, line);
584 MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", nodeId);
586 } /* end if SERVER */
587 else { /* if CLIENT */
589 /* It is a request for a previous upload segment. We should find a line opened for this.*/
590 err = getSDOlineOnUse( d, nodeId, whoami, &line);
592 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
594 MSG_ERR(0x1A75, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
595 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
598 /* Reset the wathdog */
599 RestartSDO_TIMER(line)
600 index = d->transfers[line].index;
601 subIndex = d->transfers[line].subIndex;
602 /* test of the toggle; */
603 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
604 MSG_ERR(0x1A76, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
605 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
608 /* nb of data to be uploaded */
609 nbBytes = 7 - getSDOn3(m->data[0]);
610 /* Storing the data in the line structure. */
611 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
613 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
616 /* Inverting the toggle for the next segment. */
617 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
618 /* If it was the last segment,*/
619 if ( getSDOc(m->data[0])) {
620 /* Put in state finished */
621 /* The code is safe for the case e=s=0 in initiate frame. */
623 d->transfers[line].state = SDO_FINISHED;
624 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
626 MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId);
628 else { /* more segments to receive */
629 /* Sending the request for the next segment. */
631 sdo.body.data[0] = (3 << 5) | (d->transfers[line].toggle << 4);
632 for (i = 1 ; i < 8 ; i++)
633 sdo.body.data[i] = 0;
634 sendSDO(d, whoami, sdo);
635 MSG_WAR(0x3A78, "SDO send upload segment request to nodeId", nodeId);
637 } /* End if CLIENT */
642 /* Receive of an initiate download */
643 if (whoami == SDO_SERVER) {
644 index = getSDOindex(m->data[1],m->data[2]);
645 subIndex = getSDOsubIndex(m->data[3]);
646 MSG_WAR(0x3A79, "Received SDO Initiate Download (to store data) defined at index 0x1200 + ",
648 MSG_WAR(0x3A80, "Writing at index : ", index);
649 MSG_WAR(0x3A80, "Writing at subIndex : ", subIndex);
651 /* Search if a SDO transfert have been yet initiated */
652 err = getSDOlineOnUse( d, nodeId, whoami, &line );
654 MSG_ERR(0x1A81, "SDO error : Transmission yet started.", 0);
655 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
658 /* No line on use. Great ! */
659 /* Try to open a new line. */
660 err = getSDOfreeLine( d, whoami, &line );
662 MSG_ERR(0x1A82, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
663 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
666 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
668 if (getSDOe(m->data[0])) { /* If SDO expedited */
669 /* nb of data to be downloaded */
670 nbBytes = 4 - getSDOn2(m->data[0]);
671 /* Storing the data in the line structure. */
672 d->transfers[line].count = nbBytes;
673 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
676 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
680 /* SDO expedited -> transfert finished. Data can be stored in the dictionary. */
681 /* The line will be reseted when it is downloading in the dictionary. */
682 MSG_WAR(0x3A83, "SDO Initiate Download is an expedited transfert. Finished.: ", nodeId);
683 /* Transfering line data to object dictionary. */
684 errorCode = SDOlineToObjdict(d, line);
686 MSG_ERR(0x1A84, "SDO error : Unable to copy the data in the object dictionary", 0);
687 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
690 /* Release of the line. */
691 resetSDOline(d, line);
693 else {/* So, if it is not an expedited transfert */
694 if (getSDOs(m->data[0])) {
695 /* TODO : if e and s = 0, not reading m->data[4] but put nbBytes = 0 */
696 nbBytes = m->data[4]; /* Transfert limited to 255 bytes. */
697 err = setSDOlineRestBytes(d, nodeId, nbBytes);
699 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
704 /*Sending a SDO, cs=3*/
705 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender).*/
706 sdo.body.data[0] = 3 << 5;
707 sdo.body.data[1] = index & 0xFF; /* LSB */
708 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
709 sdo.body.data[3] = subIndex;
710 for (i = 4 ; i < 8 ; i++)
711 sdo.body.data[i] = 0;
712 sendSDO(d, whoami, sdo);
713 } /* end if I am SERVER */
716 /* It is a response for a previous download segment. We should find a line opened for this. */
717 err = getSDOlineOnUse( d, nodeId, whoami, &line);
719 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
721 MSG_ERR(0x1A85, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
722 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
725 /* Reset the wathdog */
726 RestartSDO_TIMER(line)
727 index = d->transfers[line].index;
728 subIndex = d->transfers[line].subIndex;
729 /* test of the toggle; */
730 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
731 MSG_ERR(0x1A86, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
732 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
736 /* End transmission or downloading next segment. We need to know if it will be the last one. */
737 getSDOlineRestBytes(d, line, &nbBytes);
739 MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId);
741 d->transfers[line].state = SDO_FINISHED;
742 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
745 /* At least one transfer to send. */
747 /* several segments to download.*/
748 /* code to send the next segment. (cs = 0; c = 0) */
749 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
750 sdo.nodeId = nodeId; /* The server node Id; */
751 sdo.body.data[0] = (d->transfers[line].toggle << 4);
752 err = lineToSDO(d, line, 7, sdo.body.data + 1);
754 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
760 /* code to send the last segment. (cs = 0; c = 1)*/
761 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
762 sdo.nodeId = nodeId; /* The server node Id; */
763 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
764 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
766 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
769 for (i = nbBytes + 1 ; i < 8 ; i++)
770 sdo.body.data[i] = 0;
772 MSG_WAR(0x3A88, "SDO sending download segment to nodeId", nodeId);
773 sendSDO(d, whoami, sdo);
774 } /* end if I am a CLIENT */
779 /* Receive of an initiate upload.*/
780 if (whoami == SDO_SERVER) {
781 index = getSDOindex(m->data[1],m->data[2]);
782 subIndex = getSDOsubIndex(m->data[3]);
783 MSG_WAR(0x3A89, "Received SDO Initiate upload (to send data) defined at index 0x1200 + ",
785 MSG_WAR(0x3A90, "Reading at index : ", index);
786 MSG_WAR(0x3A91, "Reading at subIndex : ", subIndex);
787 /* Search if a SDO transfert have been yet initiated*/
788 err = getSDOlineOnUse( d, nodeId, whoami, &line );
790 MSG_ERR(0x1A92, "SDO error : Transmission yet started at line : ", line);
791 MSG_WAR(0x3A93, "nodeId = ", nodeId);
792 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
795 /* No line on use. Great !*/
796 /* Try to open a new line.*/
797 err = getSDOfreeLine( d, whoami, &line );
799 MSG_ERR(0x1A71, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
800 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
803 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
804 /* Transfer data from dictionary to the line structure. */
805 errorCode = objdictToSDOline(d, line);
808 MSG_ERR(0x1A94, "SDO error : Unable to copy the data from object dictionary. Err code : ",
810 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
813 /* Preparing the response.*/
814 getSDOlineRestBytes(d, line, &nbBytes); /* Nb bytes to transfer ? */
815 sdo.nodeId = nodeId; /* The server node Id; */
817 /* normal transfert. (segmented). */
818 /* code to send the initiate upload response. (cs = 2) */
819 sdo.body.data[0] = (2 << 5) | 1;
820 sdo.body.data[1] = index & 0xFF; /* LSB */
821 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
822 sdo.body.data[3] = subIndex;
823 sdo.body.data[4] = nbBytes; /* Limitation of canfestival2 : Max tranfert is 256 bytes.*/
824 /* It takes too much memory to upgrate to 2^32 because the size of data is also coded */
825 /* in the object dictionary, at every index and subindex. */
826 for (i = 5 ; i < 8 ; i++)
827 sdo.body.data[i] = 0;
828 MSG_WAR(0x3A95, "SDO. Sending normal upload initiate response defined at index 0x1200 + ", nodeId);
829 sendSDO(d, whoami, sdo);
832 /* Expedited upload. (cs = 2 ; e = 1) */
833 sdo.body.data[0] = (2 << 5) | ((4 - nbBytes) << 2) | 3;
834 sdo.body.data[1] = index & 0xFF; /* LSB */
835 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
836 sdo.body.data[3] = subIndex;
837 err = lineToSDO(d, line, nbBytes, sdo.body.data + 4);
839 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
842 for (i = 4 + nbBytes ; i < 8 ; i++)
843 sdo.body.data[i] = 0;
844 MSG_WAR(0x3A96, "SDO. Sending expedited upload initiate response defined at index 0x1200 + ",
846 sendSDO(d, whoami, sdo);
847 /* Release the line.*/
848 resetSDOline(d, line);
850 } /* end if I am SERVER*/
853 /* It is the response for the previous initiate upload request.*/
854 /* We should find a line opened for this. */
855 err = getSDOlineOnUse( d, nodeId, whoami, &line);
857 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
859 MSG_ERR(0x1A97, "SDO error : Received response for unknown upload request from nodeId", nodeId);
860 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
863 /* Reset the wathdog */
864 RestartSDO_TIMER(line)
865 index = d->transfers[line].index;
866 subIndex = d->transfers[line].subIndex;
868 if (getSDOe(m->data[0])) { /* If SDO expedited */
869 /* nb of data to be uploaded */
870 nbBytes = 4 - getSDOn2(m->data[0]);
871 /* Storing the data in the line structure. */
872 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
874 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
877 /* SDO expedited -> transfert finished. data are available via getReadResultNetworkDict(). */
878 MSG_WAR(0x3A98, "SDO expedited upload finished. Response received from node : ", nodeId);
880 d->transfers[line].count = nbBytes;
881 d->transfers[line].state = SDO_FINISHED;
882 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
885 else { /* So, if it is not an expedited transfert */
886 /* Storing the nb of data to receive. */
887 if (getSDOs(m->data[0])) {
888 nbBytes = m->data[4]; /* Remember the limitation to 255 bytes to transfert */
889 err = setSDOlineRestBytes(d, line, nbBytes);
891 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
895 /* Requesting next segment. (cs = 3) */
897 sdo.body.data[0] = 3 << 5;
898 for (i = 1 ; i < 8 ; i++)
899 sdo.body.data[i] = 0;
900 MSG_WAR(0x3A99, "SDO. Sending upload segment request to node : ", nodeId);
901 sendSDO(d, whoami, sdo);
903 } /* End if CLIENT */
908 if (whoami == SDO_SERVER) {
909 /* Receiving a upload segment. */
910 /* A SDO transfert should have been yet initiated. */
911 err = getSDOlineOnUse( d, nodeId, whoami, &line );
913 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
915 MSG_ERR(0x1AA0, "SDO error : Received upload segment for unstarted trans. index 0x1200 + ",
917 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
920 /* Reset the wathdog */
921 RestartSDO_TIMER(line)
922 MSG_WAR(0x3AA1, "Received SDO upload segment defined at index 0x1200 + ", nodeId);
923 index = d->transfers[line].index;
924 subIndex = d->transfers[line].subIndex;
926 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
927 MSG_ERR(0x1AA2, "SDO error : Toggle error : ", getSDOt(m->data[0]));
928 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
931 /* Uploading next segment. We need to know if it will be the last one. */
932 getSDOlineRestBytes(d, line, &nbBytes);
934 /* The segment to transfer is not the last one.*/
935 /* code to send the next segment. (cs = 0; c = 0) */
936 sdo.nodeId = nodeId; /* The server node Id; */
937 sdo.body.data[0] = (d->transfers[line].toggle << 4);
938 err = lineToSDO(d, line, 7, sdo.body.data + 1);
940 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
943 /* Inverting the toggle for the next tranfert. */
944 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
945 MSG_WAR(0x3AA3, "SDO. Sending upload segment defined at index 0x1200 + ", nodeId);
946 sendSDO(d, whoami, sdo);
950 /* code to send the last segment. (cs = 0; c = 1) */
951 sdo.nodeId = nodeId; /* The server node Id; */
952 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
953 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
955 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
958 for (i = nbBytes + 1 ; i < 8 ; i++)
959 sdo.body.data[i] = 0;
960 MSG_WAR(0x3AA4, "SDO. Sending last upload segment defined at index 0x1200 + ", nodeId);
961 sendSDO(d, whoami, sdo);
962 /* Release the line */
963 resetSDOline(d, line);
968 /* It is the response for the previous initiate download request. */
969 /* We should find a line opened for this. */
970 err = getSDOlineOnUse( d, nodeId, whoami, &line);
972 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
974 MSG_ERR(0x1AA5, "SDO error : Received response for unknown download request from nodeId", nodeId);
975 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
978 /* Reset the wathdog */
979 RestartSDO_TIMER(line)
980 index = d->transfers[line].index;
981 subIndex = d->transfers[line].subIndex;
982 /* End transmission or requesting next segment. */
983 getSDOlineRestBytes(d, line, &nbBytes);
985 MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId);
987 d->transfers[line].state = SDO_FINISHED;
988 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
992 /* more than one request to send */
993 /* code to send the next segment. (cs = 0; c = 0) */
994 sdo.nodeId = nodeId; /* The server node Id; */
995 sdo.body.data[0] = (d->transfers[line].toggle << 4);
996 err = lineToSDO(d, line, 7, sdo.body.data + 1);
998 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1004 /* code to send the last segment. (cs = 0; c = 1) */
1005 sdo.nodeId = nodeId; /* The server node Id; */
1006 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
1007 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
1009 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1012 for (i = nbBytes + 1 ; i < 8 ; i++)
1013 sdo.body.data[i] = 0;
1015 MSG_WAR(0x3AA7, "SDO sending download segment to nodeId", nodeId);
1016 sendSDO(d, whoami, sdo);
1018 } /* end if I am a CLIENT */
1022 abortCode = (*m).data[3] |
1023 ((UNS32)m->data[5] << 8) |
1024 ((UNS32)m->data[6] << 16) |
1025 ((UNS32)m->data[7] << 24);
1026 /* Received SDO abort. */
1027 /* Looking for the line concerned. */
1028 if (whoami == SDO_SERVER) {
1029 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1031 resetSDOline( d, line );
1032 MSG_WAR(0x3AA8, "SD0. Received SDO abort. Line released. Code : ", abortCode);
1035 MSG_WAR(0x3AA9, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1036 /* Tips : The end user has no way to know that the server node has received an abort SDO. */
1037 /* Its is ok, I think.*/
1039 else { /* If I am CLIENT */
1040 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1042 /* The line *must* be released by the core program. */
1044 d->transfers[line].state = SDO_ABORTED_RCV;
1045 MSG_WAR(0x3AB0, "SD0. Received SDO abort. Line state ABORTED. Code : ", abortCode);
1048 MSG_WAR(0x3AB1, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1052 /* Error : Unknown cs */
1053 MSG_ERR(0x1AB2, "SDO. Received unknown command specifier : ", getSDOcs(m->data[0]));
1060 /*******************************************************************)******/
1061 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1062 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback)
1067 s_SDO sdo; /* SDO to transmit */
1071 UNS32 *pNodeIdServer;
1074 MSG_WAR(0x3AC0, "Send SDO to write in the dictionary of node : ", nodeId);
1075 MSG_WAR(0x3AC1, " At index : ", index);
1076 MSG_WAR(0x3AC2, " subIndex : ", subIndex);
1077 MSG_WAR(0x3AC3, " nb bytes : ", count);
1079 /* Verify that there is no SDO communication yet. */
1080 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1082 MSG_ERR(0x1AC4, "SDO error : Communication yet established. with node : ", nodeId);
1085 /* Taking the line ... */
1086 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1088 MSG_ERR(0x1AC5, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1091 /* Check which SDO to use to communicate with the node */
1092 offset = d->firstIndex->SDO_CLT;
1093 lastIndex = d->lastIndex->SDO_CLT;
1095 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
1099 while (offset <= lastIndex) {
1100 if (d->objdict[offset].bSubCount <= 3) {
1101 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
1104 /* looking for the nodeId server */
1105 pNodeIdServer = d->objdict[offset].pSubindex[3].pObject;
1106 nodeIdServer = *pNodeIdServer;
1107 MSG_WAR(0x1AD2, "index : ", 0x1280 + i);
1108 MSG_WAR(0x1AD3, "nodeIdServer : ", nodeIdServer);
1110 if(nodeIdServer == (UNS32)nodeId) {
1118 MSG_ERR(0x1AC9, "SDO. Error. No client found to communicate with node : ", nodeId);
1121 MSG_WAR(0x3AD0," SDO client defined at index : ", 0x1280 + i);
1122 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
1123 d->transfers[line].count = count;
1124 d->transfers[line].dataType = dataType;
1126 /* Copy data to transfers structure. */
1127 for (j = 0 ; j < count ; j++) {
1128 # ifdef CANOPEN_BIG_ENDIAN
1130 d->transfers[line].data[count - 1 - j] = ((char *)data)[j];
1131 else /* String of bytes. */
1132 d->transfers[line].data[j] = ((char *)data)[j];
1134 d->transfers[line].data[j] = ((char *)data)[j];
1137 /* Send the SDO to the server. Initiate download, cs=1. */
1138 sdo.nodeId = nodeId;
1139 if (count <= 4) { /* Expedited transfert */
1140 sdo.body.data[0] = (1 << 5) | ((4 - count) << 2) | 3;
1141 for (i = 4 ; i < 8 ; i++)
1142 sdo.body.data[i] = d->transfers[line].data[i - 4];
1143 d->transfers[line].offset = count;
1145 else { /* Normal transfert */
1146 sdo.body.data[0] = (1 << 5) | 1;
1147 sdo.body.data[4] = count; /* nb of byte to transmit. Max = 255. (canfestival2 limitation). */
1148 for (i = 5 ; i < 8 ; i++)
1149 sdo.body.data[i] = 0;
1151 sdo.body.data[1] = index & 0xFF; /* LSB */
1152 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1153 sdo.body.data[3] = subIndex;
1155 err = sendSDO(d, SDO_CLIENT, sdo);
1157 MSG_ERR(0x1AD1, "SDO. Error while sending SDO to node : ", nodeId);
1158 /* release the line */
1159 resetSDOline(d, line);
1162 d->transfers[line].Callback = Callback;
1166 /*--------------------------------------------------------------------------*/
1168 UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1169 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data)
1171 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, NULL);
1174 /*--------------------------------------------------------------------------*/
1176 UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index,
1177 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback)
1179 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback);
1183 /***************************************************************************/
1184 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1190 s_SDO sdo; /* SDO to transmit */
1191 UNS32 *pNodeIdServer;
1195 MSG_WAR(0x3AD5, "Send SDO to read in the dictionary of node : ", nodeId);
1196 MSG_WAR(0x3AD6, " At index : ", index);
1197 MSG_WAR(0x3AD7, " subIndex : ", subIndex);
1200 /* Verify that there is no SDO communication yet. */
1201 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1203 MSG_ERR(0x1AD8, "SDO error : Communication yet established. with node : ", nodeId);
1206 /* Taking the line ... */
1207 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1209 MSG_ERR(0x1AD9, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1213 MSG_WAR(0x3AE0, "Transmission on line : ", line);
1215 /* Check which SDO to use to communicate with the node */
1216 offset = d->firstIndex->SDO_CLT;
1217 lastIndex = d->lastIndex->SDO_CLT;
1219 MSG_ERR(0x1AE1, "writeNetworkDict : No SDO client index found", 0);
1223 while (offset <= lastIndex) {
1224 if (d->objdict[offset].bSubCount <= 3) {
1225 MSG_ERR(0x1AE2, "Subindex 3 not found at index ", 0x1280 + i);
1228 /* looking for the nodeId server */
1229 pNodeIdServer = d->objdict[offset].pSubindex[3].pObject;
1230 nodeIdServer = *pNodeIdServer;
1232 if(nodeIdServer == (UNS32)nodeId) {
1240 MSG_ERR(0x1AE3, "SDO. Error. No client found to communicate with node : ", nodeId);
1243 MSG_WAR(0x3AE4," SDO client defined at index : ", 0x1280 + i);
1244 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
1245 getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1246 sdo.nodeId = nodeId;
1247 /* Send the SDO to the server. Initiate upload, cs=2. */
1248 d->transfers[line].dataType = dataType;
1249 sdo.body.data[0] = (2 << 5);
1250 sdo.body.data[1] = index & 0xFF; /* LSB */
1251 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1252 sdo.body.data[3] = subIndex;
1253 for (i = 4 ; i < 8 ; i++)
1254 sdo.body.data[i] = 0;
1255 err = sendSDO(d, SDO_CLIENT, sdo);
1257 MSG_ERR(0x1AE5, "SDO. Error while sending SDO to node : ", nodeId);
1258 /* release the line */
1259 resetSDOline(d, line);
1262 d->transfers[line].Callback = Callback;
1266 /*--------------------------------------------------------------------------*/
1268 UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType)
1270 return _readNetworkDict (d, nodeId, index, subIndex, dataType, NULL);
1273 /*--------------------------------------------------------------------------*/
1274 UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1276 return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
1279 /***************************************************************************/
1281 UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size,
1289 /* Looking for the line tranfert. */
1290 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1292 MSG_ERR(0x1AF0, "SDO error : No line found for communication with node : ", nodeId);
1293 return SDO_ABORTED_INTERNAL;
1295 if (d->transfers[line].state != SDO_FINISHED)
1296 return d->transfers[line].state;
1298 /* Transfert is finished. Put the value in the data. */
1299 * size = d->transfers[line].count;
1300 for ( i = 0 ; i < *size ; i++) {
1301 # ifdef CANOPEN_BIG_ENDIAN
1302 if (d->transfers[line].dataType != visible_string)
1303 ( (char *) data)[*size - 1 - i] = d->transfers[line].data[i];
1304 else /* String of bytes. */
1305 ( (char *) data)[i] = d->transfers[line].data[i];
1307 ( (char *) data)[i] = d->transfers[line].data[i];
1310 return SDO_FINISHED;
1313 /***************************************************************************/
1315 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode)
1321 /* Looking for the line tranfert. */
1322 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1324 MSG_ERR(0x1AF1, "SDO error : No line found for communication with node : ", nodeId);
1325 return SDO_ABORTED_INTERNAL;
1327 * abortCode = d->transfers[line].abortCode;
1328 return d->transfers[line].state;