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
24 ** @author Edouard TISSERANT and Francis DUPIN
25 ** @date Tue Jun 5 09:32:32 2007
32 /* #define DEBUG_WAR_CONSOLE_ON */
33 /* #define DEBUG_ERR_CONSOLE_ON */
37 #include "canfestival.h"
40 /* Uncomment if your compiler does not support inline functions */
49 /*Internals prototypes*/
52 ** Called by writeNetworkDict
66 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
67 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize);
70 ** Called by readNetworkDict
81 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex,
82 UNS8 dataType, SDOCallback_t Callback);
85 /***************************************************************************/
86 /* SDO (un)packing macros */
88 /** Returns the command specifier (cs, ccs, scs) from the first byte of the SDO
90 #define getSDOcs(byte) (byte >> 5)
92 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 2 bits
94 #define getSDOn2(byte) ((byte >> 2) & 3)
96 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 3 bits
98 #define getSDOn3(byte) ((byte >> 1) & 7)
100 /** Returns the transfer type from the first byte of the SDO
102 #define getSDOe(byte) ((byte >> 1) & 1)
104 /** Returns the size indicator from the first byte of the SDO
106 #define getSDOs(byte) (byte & 1)
108 /** Returns the indicator of end transmission from the first byte of the SDO
110 #define getSDOc(byte) (byte & 1)
112 /** Returns the toggle from the first byte of the SDO
114 #define getSDOt(byte) ((byte >> 4) & 1)
116 /** Returns the index from the bytes 1 and 2 of the SDO
118 #define getSDOindex(byte1, byte2) ((byte2 << 8) | (byte1))
120 /** Returns the subIndex from the byte 3 of the SDO
122 #define getSDOsubIndex(byte3) (byte3)
130 void SDOTimeoutAlarm(CO_Data* d, UNS32 id)
132 MSG_ERR(0x1A01, "SDO timeout. SDO response not received.", 0);
133 MSG_WAR(0x2A02, "server node : ", d->transfers[id].nodeId);
134 MSG_WAR(0x2A02, " index : ", d->transfers[id].index);
135 MSG_WAR(0x2A02, " subIndex : ", d->transfers[id].subIndex);
136 /* Reset timer handler */
137 d->transfers[id].timer = TIMER_NONE;
138 /*Set aborted state*/
139 d->transfers[id].state = SDO_ABORTED_INTERNAL;
140 /* Sending a SDO abort */
141 sendSDOabort(d, d->transfers[id].whoami,
142 d->transfers[id].index, d->transfers[id].subIndex, SDOABT_TIMED_OUT);
143 d->transfers[id].abortCode = SDOABT_TIMED_OUT;
144 /* Call the user function to inform of the problem.*/
145 if(d->transfers[id].Callback)
146 /*If ther is a callback, it is responsible to close SDO transfer (client)*/
147 (*d->transfers[id].Callback)(d,d->transfers[id].nodeId);
148 else if(d->transfers[id].whoami == SDO_SERVER)
149 /*Else, if server, reset the line*/
150 resetSDOline(d, (UNS8)id);
153 #define StopSDO_TIMER(id) \
154 MSG_WAR(0x3A05, "StopSDO_TIMER for line : ", line);\
155 d->transfers[id].timer = DelAlarm(d->transfers[id].timer);
157 #define StartSDO_TIMER(id) \
158 MSG_WAR(0x3A06, "StartSDO_TIMER for line : ", line);\
159 d->transfers[id].timer = SetAlarm(d,id,&SDOTimeoutAlarm,MS_TO_TIMEVAL(SDO_TIMEOUT_MS),0);
161 #define RestartSDO_TIMER(id) \
162 MSG_WAR(0x3A07, "restartSDO_TIMER for line : ", line);\
163 if(d->transfers[id].timer != TIMER_NONE) { StopSDO_TIMER(id) StartSDO_TIMER(id) }
166 ** Reset all sdo buffers
170 void resetSDO (CO_Data* d)
174 /* transfer structure initialization */
175 for (j = 0 ; j < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; j++)
187 UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line)
191 MSG_WAR(0x3A08, "Enter in SDOlineToObjdict ", line);
192 size = (UNS8)d->transfers[line].count;
193 errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
194 (void *) d->transfers[line].data, &size, 1);
195 if (errorCode != OD_SUCCESSFUL)
197 MSG_WAR(0x3A08, "exit of SDOlineToObjdict ", line);
210 UNS32 objdictToSDOline (CO_Data* d, UNS8 line)
216 MSG_WAR(0x3A05, "objdict->line index : ", d->transfers[line].index);
217 MSG_WAR(0x3A06, " subIndex : ", d->transfers[line].subIndex);
219 errorCode = getODentry(d, d->transfers[line].index,
220 d->transfers[line].subIndex,
221 (void *)d->transfers[line].data,
222 &size, &dataType, 0);
224 if (errorCode != OD_SUCCESSFUL)
227 d->transfers[line].count = size;
228 d->transfers[line].offset = 0;
230 /*Me laisser a, please ! (FD)*/
233 for (i = 0 ; i < 10 ; i++) {
234 MSG_WAR(i, "data= ", d->transfers[line].data[i]);
251 UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data) {
255 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
256 MSG_ERR(0x1A10,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
259 if ((d->transfers[line].offset + nbBytes) > d->transfers[line].count) {
260 MSG_ERR(0x1A11,"SDO Size of data too large. Exceed count", nbBytes);
263 offset = (UNS8)d->transfers[line].offset;
264 for (i = 0 ; i < nbBytes ; i++)
265 * (data + i) = d->transfers[line].data[offset + i];
266 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
280 UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data)
285 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
286 MSG_ERR(0x1A15,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
289 offset = (UNS8)d->transfers[line].offset;
290 for (i = 0 ; i < nbBytes ; i++)
291 d->transfers[line].data[offset + i] = * (data + i);
292 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
308 UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index,
309 UNS8 subIndex, UNS32 abortCode)
313 err = getSDOlineOnUse( d, nodeId, whoami, &line );
314 if (!err) /* If a line on use have been found.*/
315 MSG_WAR(0x3A20, "FailedSDO : line found : ", line);
316 if ((! err) && (whoami == SDO_SERVER)) {
317 resetSDOline( d, line );
318 MSG_WAR(0x3A21, "FailedSDO : line released : ", line);
320 if ((! err) && (whoami == SDO_CLIENT)) {
322 d->transfers[line].state = SDO_ABORTED_INTERNAL;
324 MSG_WAR(0x3A22, "Sending SDO abort ", 0);
325 err = sendSDOabort(d, whoami, index, subIndex, abortCode);
327 MSG_WAR(0x3A23, "Unable to send the SDO abort", 0);
339 void resetSDOline ( CO_Data* d, UNS8 line )
342 MSG_WAR(0x3A25, "reset SDO line nb : ", line);
343 initSDOline(d, line, 0, 0, 0, SDO_RESET);
344 for (i = 0 ; i < SDO_MAX_LENGTH_TRANSFERT ; i++)
345 d->transfers[line].data[i] = 0;
360 UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state)
362 MSG_WAR(0x3A25, "init SDO line nb : ", line);
363 if (state == SDO_DOWNLOAD_IN_PROGRESS || state == SDO_UPLOAD_IN_PROGRESS){
368 d->transfers[line].nodeId = nodeId;
369 d->transfers[line].index = index;
370 d->transfers[line].subIndex = subIndex;
371 d->transfers[line].state = state;
372 d->transfers[line].toggle = 0;
373 d->transfers[line].count = 0;
374 d->transfers[line].offset = 0;
375 d->transfers[line].dataType = 0;
376 d->transfers[line].Callback = NULL;
389 UNS8 getSDOfreeLine ( CO_Data* d, UNS8 whoami, UNS8 *line )
394 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
395 if ( d->transfers[i].state == SDO_RESET ) {
397 d->transfers[i].whoami = whoami;
401 MSG_ERR(0x1A25, "Too many SDO in progress. Aborted.", i);
415 UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line)
420 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
421 if ( (d->transfers[i].state != SDO_RESET) &&
422 (d->transfers[i].nodeId == nodeId) &&
423 (d->transfers[i].whoami == whoami) ) {
440 UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami)
444 err = getSDOlineOnUse(d, nodeId, whoami, &line);
446 MSG_WAR(0x2A30, "No SDO communication to close for node : ", nodeId);
449 resetSDOline(d, line);
462 UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 * nbBytes)
464 if (d->transfers[line].count == 0) /* if received initiate SDO protocol with e=0 and s=0 */
467 * nbBytes = (UNS8)d->transfers[line].count - (UNS8)d->transfers[line].offset;
480 UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 nbBytes)
482 if (nbBytes > SDO_MAX_LENGTH_TRANSFERT) {
483 MSG_ERR(0x1A35,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
486 d->transfers[line].count = nbBytes;
499 UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo)
506 UNS16 * pwCobId = NULL;
507 UNS8 * pwNodeId = NULL;
509 MSG_WAR(0x3A38, "sendSDO",0);
510 if( !((d->nodeState == Operational) || (d->nodeState == Pre_operational ))) {
511 MSG_WAR(0x2A39, "unable to send the SDO (not in op or pre-op mode", d->nodeState);
515 /*get the server->client cobid*/
516 if ( whoami == SDO_SERVER ) {/*case server. Easy because today only one server SDO is authorized in CanFestival*/
517 offset = d->firstIndex->SDO_SVR;
519 MSG_ERR(0x1A42, "SendSDO : No SDO server found", 0);
522 pwCobId = (UNS32*) d->objdict[offset].pSubindex[2].pObject;
523 MSG_WAR(0x3A41, "I am server. cobId : ", *pwCobId);
525 else { /*case client*/
526 /* Get the client->server cobid.*/
528 offset = d->firstIndex->SDO_CLT;
529 lastIndex = d->lastIndex->SDO_CLT;
531 MSG_ERR(0x1A42, "SendSDO : No SDO client index found", 0);
534 /* First, have to find at the index where is defined the communication with the server node */
535 while (offset <= lastIndex){
536 MSG_WAR(0x3A43,"Reading index : ", 0x1280 + sdoNum);
537 if (d->objdict[offset].bSubCount <= 3) {
538 MSG_ERR(0x1A28, "Subindex 3 not found at index ", 0x1280 + sdoNum);
541 pwNodeId = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
542 MSG_WAR(0x3A44, "Found nodeId server = ", *pwNodeId);
543 if(*pwNodeId == sdo.nodeId) {
551 MSG_WAR (0x2A45, "No SDO client corresponds to the mesage to send to node ", sdo.nodeId);
554 /* Second, read the cobid client->server */
555 pwCobId = (UNS16*) d->objdict[offset].pSubindex[1].pObject;
557 /* message copy for sending */
559 m.rtr = NOT_A_REQUEST;
560 /* the length of SDO must be 8 */
562 for (i = 0 ; i < 8 ; i++) {
563 m.data[i] = sdo.body.data[i];
565 return canSend(d->canHandle,&m);
579 UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS16 index, UNS8 subIndex, UNS32 abortCode)
583 MSG_WAR(0x2A50,"Sending SDO abort ", abortCode);
584 sdo.nodeId = *d->bDeviceNodeId;
585 sdo.body.data[0] = 0x80;
587 sdo.body.data[1] = index & 0xFF; /* LSB */
588 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
590 sdo.body.data[3] = subIndex;
592 sdo.body.data[4] = (UNS8)(abortCode & 0xFF);
593 sdo.body.data[5] = (UNS8)((abortCode >> 8) & 0xFF);
594 sdo.body.data[6] = (UNS8)((abortCode >> 16) & 0xFF);
595 sdo.body.data[7] = (UNS8)((abortCode >> 24) & 0xFF);
596 ret = sendSDO(d, whoami, sdo);
609 UNS8 proceedSDO (CO_Data* d, Message *m)
613 UNS8 nbBytes; /* received or to be transmited. */
614 UNS8 nodeId = 0; /* The node from which the SDO is received */
615 UNS8 *pNodeId = NULL;
616 UNS8 whoami = SDO_UNKNOWN; /* SDO_SERVER or SDO_CLIENT.*/
617 UNS32 errorCode; /* while reading or writing in the local object dictionary.*/
618 s_SDO sdo; /* SDO to transmit */
623 UNS16 *pCobId = NULL;
627 MSG_WAR(0x3A60, "proceedSDO ", 0);
628 whoami = SDO_UNKNOWN;
629 /* Looking for the cobId in the object dictionary. */
630 /* Am-I a server ? */
631 offset = d->firstIndex->SDO_SVR;
632 lastIndex = d->lastIndex->SDO_SVR;
634 if(offset) while (offset <= lastIndex) {
635 if (d->objdict[offset].bSubCount <= 1) {
636 MSG_ERR(0x1A61, "Subindex 1 not found at index ", 0x1200 + j);
639 pCobId = (UNS16*) d->objdict[offset].pSubindex[1].pObject;
640 if ( *pCobId == (*m).cob_id ) {
642 MSG_WAR(0x3A62, "proceedSDO. I am server. index : ", 0x1200 + j);
643 /* In case of server, the node id of the client may be unknown. So we put the index minus offset */
644 /* 0x1200 where the cobid received is defined. */
651 if (whoami == SDO_UNKNOWN) {
653 offset = d->firstIndex->SDO_CLT;
654 lastIndex = d->lastIndex->SDO_CLT;
656 if(offset) while (offset <= lastIndex) {
657 if (d->objdict[offset].bSubCount <= 3) {
658 MSG_ERR(0x1A63, "Subindex 3 not found at index ", 0x1280 + j);
661 /* a) Looking for the cobid received. */
662 pCobId = (UNS16*) d->objdict[offset].pSubindex[2].pObject;
663 if (*pCobId == (*m).cob_id ) {
664 /* b) cobid found, so reading the node id of the server. */
665 pNodeId = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
668 MSG_WAR(0x3A64, "proceedSDO. I am server. index : ", 0x1280 + j);
669 MSG_WAR(0x3A65, " Server nodeId : ", nodeId);
676 if (whoami == SDO_UNKNOWN) {
677 return 0xFF;/* This SDO was not for us ! */
680 /* Test if the size of the SDO is ok */
681 if ( (*m).len != 8) {
682 MSG_ERR(0x1A67, "Error size SDO. CobId : ", (*m).cob_id);
683 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_GENERAL_ERROR);
687 if (whoami == SDO_CLIENT) {
688 MSG_WAR(0x3A68, "I am CLIENT. Received SDO from nodeId : ", nodeId);
691 MSG_WAR(0x3A69, "I am SERVER. Received SDO cobId : ", (*m).cob_id);
694 /* Testing the command specifier */
695 /* Allowed : cs = 0, 1, 2, 3, 4. (= all except those for block tranfert). */
696 /* cs = other : Not allowed -> abort. */
697 switch (getSDOcs(m->data[0])) {
701 if (whoami == SDO_SERVER) {
702 /* Receiving a download segment data. */
703 /* A SDO transfert should have been yet initiated. */
704 err = getSDOlineOnUse( d, nodeId, whoami, &line );
706 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
708 MSG_ERR(0x1A70, "SDO error : Received download segment for unstarted trans. index 0x1200 + ",
710 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
713 /* Reset the wathdog */
714 RestartSDO_TIMER(line)
715 MSG_WAR(0x3A71, "Received SDO download segment defined at index 0x1200 + ", nodeId);
716 index = d->transfers[line].index;
717 subIndex = d->transfers[line].subIndex;
719 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
720 MSG_ERR(0x1A72, "SDO error : Toggle error : ", getSDOt(m->data[0]));
721 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
724 /* Nb of data to be downloaded */
725 nbBytes = 7 - getSDOn3(m->data[0]);
726 /* Store the data in the transfert structure. */
727 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
729 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
732 /* Sending the SDO response, CS = 1 */
733 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender). */
734 sdo.body.data[0] = (1 << 5) | (d->transfers[line].toggle << 4);
735 for (i = 1 ; i < 8 ; i++)
736 sdo.body.data[i] = 0;
737 MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", nodeId);
738 sendSDO(d, whoami, sdo);
739 /* Inverting the toggle for the next segment. */
740 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
741 /* If it was the last segment, */
742 if (getSDOc(m->data[0])) {
743 /* Transfering line data to object dictionary. */
744 /* The code does not use the "d" of initiate frame. So it is safe if e=s=0 */
745 errorCode = SDOlineToObjdict(d, line);
747 MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0);
748 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
751 /* Release of the line */
752 resetSDOline(d, line);
753 MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", nodeId);
755 } /* end if SERVER */
756 else { /* if CLIENT */
758 /* It is a request for a previous upload segment. We should find a line opened for this.*/
759 err = getSDOlineOnUse( d, nodeId, whoami, &line);
761 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
763 MSG_ERR(0x1A75, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
764 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
767 /* Reset the wathdog */
768 RestartSDO_TIMER(line)
769 index = d->transfers[line].index;
770 subIndex = d->transfers[line].subIndex;
771 /* test of the toggle; */
772 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
773 MSG_ERR(0x1A76, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
774 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
777 /* nb of data to be uploaded */
778 nbBytes = 7 - getSDOn3(m->data[0]);
779 /* Storing the data in the line structure. */
780 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
782 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
785 /* Inverting the toggle for the next segment. */
786 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
787 /* If it was the last segment,*/
788 if ( getSDOc(m->data[0])) {
789 /* Put in state finished */
790 /* The code is safe for the case e=s=0 in initiate frame. */
792 d->transfers[line].state = SDO_FINISHED;
793 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
795 MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId);
797 else { /* more segments to receive */
798 /* Sending the request for the next segment. */
800 sdo.body.data[0] = (3 << 5) | (d->transfers[line].toggle << 4);
801 for (i = 1 ; i < 8 ; i++)
802 sdo.body.data[i] = 0;
803 sendSDO(d, whoami, sdo);
804 MSG_WAR(0x3A78, "SDO send upload segment request to nodeId", nodeId);
806 } /* End if CLIENT */
811 /* Receive of an initiate download */
812 if (whoami == SDO_SERVER) {
813 index = getSDOindex(m->data[1],m->data[2]);
814 subIndex = getSDOsubIndex(m->data[3]);
815 MSG_WAR(0x3A79, "Received SDO Initiate Download (to store data) defined at index 0x1200 + ",
817 MSG_WAR(0x3A80, "Writing at index : ", index);
818 MSG_WAR(0x3A80, "Writing at subIndex : ", subIndex);
820 /* Search if a SDO transfert have been yet initiated */
821 err = getSDOlineOnUse( d, nodeId, whoami, &line );
823 MSG_ERR(0x1A81, "SDO error : Transmission yet started.", 0);
824 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
827 /* No line on use. Great ! */
828 /* Try to open a new line. */
829 err = getSDOfreeLine( d, whoami, &line );
831 MSG_ERR(0x1A82, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
832 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
835 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
837 if (getSDOe(m->data[0])) { /* If SDO expedited */
838 /* nb of data to be downloaded */
839 nbBytes = 4 - getSDOn2(m->data[0]);
840 /* Storing the data in the line structure. */
841 d->transfers[line].count = nbBytes;
842 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
845 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
849 /* SDO expedited -> transfert finished. Data can be stored in the dictionary. */
850 /*The line will be reseted when it is downloading in the dictionary. */
851 MSG_WAR(0x3A83, "SDO Initiate Download is an expedited transfert. Finished.: ", nodeId);
852 /* Transfering line data to object dictionary. */
853 errorCode = SDOlineToObjdict(d, line);
855 MSG_ERR(0x1A84, "SDO error : Unable to copy the data in the object dictionary", 0);
856 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
859 /* Release of the line. */
860 resetSDOline(d, line);
862 else {/* So, if it is not an expedited transfert */
863 if (getSDOs(m->data[0])) {
864 /* TODO : if e and s = 0, not reading m->data[4] but put nbBytes = 0 */
865 nbBytes = m->data[4]; /* Transfert limited to 255 bytes. */
866 err = setSDOlineRestBytes(d, nodeId, nbBytes);
868 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
873 /*Sending a SDO, cs=3*/
874 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender).*/
875 sdo.body.data[0] = 3 << 5;
876 sdo.body.data[1] = index & 0xFF; /* LSB */
877 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
878 sdo.body.data[3] = subIndex;
879 for (i = 4 ; i < 8 ; i++)
880 sdo.body.data[i] = 0;
881 sendSDO(d, whoami, sdo);
882 } /* end if I am SERVER */
885 /* It is a response for a previous download segment. We should find a line opened for this. */
886 err = getSDOlineOnUse( d, nodeId, whoami, &line);
888 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
890 MSG_ERR(0x1A85, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
891 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
894 /* Reset the wathdog */
895 RestartSDO_TIMER(line)
896 index = d->transfers[line].index;
897 subIndex = d->transfers[line].subIndex;
898 /* test of the toggle; */
899 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
900 MSG_ERR(0x1A86, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
901 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
905 /* End transmission or downloading next segment. We need to know if it will be the last one. */
906 getSDOlineRestBytes(d, line, &nbBytes);
908 MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId);
910 d->transfers[line].state = SDO_FINISHED;
911 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
914 /* At least one transfer to send. */
916 /* several segments to download.*/
917 /* code to send the next segment. (cs = 0; c = 0) */
918 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
919 sdo.nodeId = nodeId; /* The server node Id; */
920 sdo.body.data[0] = (d->transfers[line].toggle << 4);
921 err = lineToSDO(d, line, 7, sdo.body.data + 1);
923 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
929 /* code to send the last segment. (cs = 0; c = 1)*/
930 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
931 sdo.nodeId = nodeId; /* The server node Id; */
932 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
933 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
935 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
938 for (i = nbBytes + 1 ; i < 8 ; i++)
939 sdo.body.data[i] = 0;
941 MSG_WAR(0x3A88, "SDO sending download segment to nodeId", nodeId);
942 sendSDO(d, whoami, sdo);
943 } /* end if I am a CLIENT */
948 /* Receive of an initiate upload.*/
949 if (whoami == SDO_SERVER) {
950 index = getSDOindex(m->data[1],m->data[2]);
951 subIndex = getSDOsubIndex(m->data[3]);
952 MSG_WAR(0x3A89, "Received SDO Initiate upload (to send data) defined at index 0x1200 + ",
954 MSG_WAR(0x3A90, "Reading at index : ", index);
955 MSG_WAR(0x3A91, "Reading at subIndex : ", subIndex);
956 /* Search if a SDO transfert have been yet initiated*/
957 err = getSDOlineOnUse( d, nodeId, whoami, &line );
959 MSG_ERR(0x1A92, "SDO error : Transmission yet started at line : ", line);
960 MSG_WAR(0x3A93, "nodeId = ", nodeId);
961 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
964 /* No line on use. Great !*/
965 /* Try to open a new line.*/
966 err = getSDOfreeLine( d, whoami, &line );
968 MSG_ERR(0x1A71, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
969 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
972 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
973 /* Transfer data from dictionary to the line structure. */
974 errorCode = objdictToSDOline(d, line);
977 MSG_ERR(0x1A94, "SDO error : Unable to copy the data from object dictionary. Err code : ",
979 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
982 /* Preparing the response.*/
983 getSDOlineRestBytes(d, line, &nbBytes); /* Nb bytes to transfer ? */
984 sdo.nodeId = nodeId; /* The server node Id; */
986 /* normal transfert. (segmented). */
987 /* code to send the initiate upload response. (cs = 2) */
988 sdo.body.data[0] = (2 << 5) | 1;
989 sdo.body.data[1] = index & 0xFF; /* LSB */
990 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
991 sdo.body.data[3] = subIndex;
992 sdo.body.data[4] = nbBytes; /* Limitation of canfestival2 : Max tranfert is 256 bytes.*/
993 /* It takes too much memory to upgrate to 2^32 because the size of data is also coded */
994 /* in the object dictionary, at every index and subindex. */
995 for (i = 5 ; i < 8 ; i++)
996 sdo.body.data[i] = 0;
997 MSG_WAR(0x3A95, "SDO. Sending normal upload initiate response defined at index 0x1200 + ", nodeId);
998 sendSDO(d, whoami, sdo);
1001 /* Expedited upload. (cs = 2 ; e = 1) */
1002 sdo.body.data[0] = (2 << 5) | ((4 - nbBytes) << 2) | 3;
1003 sdo.body.data[1] = index & 0xFF; /* LSB */
1004 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1005 sdo.body.data[3] = subIndex;
1006 err = lineToSDO(d, line, nbBytes, sdo.body.data + 4);
1008 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1011 for (i = 4 + nbBytes ; i < 8 ; i++)
1012 sdo.body.data[i] = 0;
1013 MSG_WAR(0x3A96, "SDO. Sending expedited upload initiate response defined at index 0x1200 + ",
1015 sendSDO(d, whoami, sdo);
1016 /* Release the line.*/
1017 resetSDOline(d, line);
1019 } /* end if I am SERVER*/
1022 /* It is the response for the previous initiate upload request.*/
1023 /* We should find a line opened for this. */
1024 err = getSDOlineOnUse( d, nodeId, whoami, &line);
1026 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
1028 MSG_ERR(0x1A97, "SDO error : Received response for unknown upload request from nodeId", nodeId);
1029 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
1032 /* Reset the wathdog */
1033 RestartSDO_TIMER(line)
1034 index = d->transfers[line].index;
1035 subIndex = d->transfers[line].subIndex;
1037 if (getSDOe(m->data[0])) { /* If SDO expedited */
1038 /* nb of data to be uploaded */
1039 nbBytes = 4 - getSDOn2(m->data[0]);
1040 /* Storing the data in the line structure. */
1041 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
1043 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1046 /* SDO expedited -> transfert finished. data are available via getReadResultNetworkDict(). */
1047 MSG_WAR(0x3A98, "SDO expedited upload finished. Response received from node : ", nodeId);
1049 d->transfers[line].count = nbBytes;
1050 d->transfers[line].state = SDO_FINISHED;
1051 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
1054 else { /* So, if it is not an expedited transfert */
1055 /* Storing the nb of data to receive. */
1056 if (getSDOs(m->data[0])) {
1057 nbBytes = m->data[4]; /* Remember the limitation to 255 bytes to transfert */
1058 err = setSDOlineRestBytes(d, line, nbBytes);
1060 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1064 /* Requesting next segment. (cs = 3) */
1065 sdo.nodeId = nodeId;
1066 sdo.body.data[0] = 3 << 5;
1067 for (i = 1 ; i < 8 ; i++)
1068 sdo.body.data[i] = 0;
1069 MSG_WAR(0x3A99, "SDO. Sending upload segment request to node : ", nodeId);
1070 sendSDO(d, whoami, sdo);
1072 } /* End if CLIENT */
1077 if (whoami == SDO_SERVER) {
1078 /* Receiving a upload segment. */
1079 /* A SDO transfert should have been yet initiated. */
1080 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1082 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
1084 MSG_ERR(0x1AA0, "SDO error : Received upload segment for unstarted trans. index 0x1200 + ",
1086 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
1089 /* Reset the wathdog */
1090 RestartSDO_TIMER(line)
1091 MSG_WAR(0x3AA1, "Received SDO upload segment defined at index 0x1200 + ", nodeId);
1092 index = d->transfers[line].index;
1093 subIndex = d->transfers[line].subIndex;
1095 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
1096 MSG_ERR(0x1AA2, "SDO error : Toggle error : ", getSDOt(m->data[0]));
1097 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
1100 /* Uploading next segment. We need to know if it will be the last one. */
1101 getSDOlineRestBytes(d, line, &nbBytes);
1103 /* The segment to transfer is not the last one.*/
1104 /* code to send the next segment. (cs = 0; c = 0) */
1105 sdo.nodeId = nodeId; /* The server node Id; */
1106 sdo.body.data[0] = (d->transfers[line].toggle << 4);
1107 err = lineToSDO(d, line, 7, sdo.body.data + 1);
1109 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1112 /* Inverting the toggle for the next tranfert. */
1113 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
1114 MSG_WAR(0x3AA3, "SDO. Sending upload segment defined at index 0x1200 + ", nodeId);
1115 sendSDO(d, whoami, sdo);
1119 /* code to send the last segment. (cs = 0; c = 1) */
1120 sdo.nodeId = nodeId; /** The server node Id; */
1121 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
1122 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
1124 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1127 for (i = nbBytes + 1 ; i < 8 ; i++)
1128 sdo.body.data[i] = 0;
1129 MSG_WAR(0x3AA4, "SDO. Sending last upload segment defined at index 0x1200 + ", nodeId);
1130 sendSDO(d, whoami, sdo);
1131 /* Release the line */
1132 resetSDOline(d, line);
1134 } /* end if SERVER*/
1137 /* It is the response for the previous initiate download request. */
1138 /* We should find a line opened for this. */
1139 err = getSDOlineOnUse( d, nodeId, whoami, &line);
1141 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
1143 MSG_ERR(0x1AA5, "SDO error : Received response for unknown download request from nodeId", nodeId);
1144 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
1147 /* Reset the watchdog */
1148 RestartSDO_TIMER(line)
1149 index = d->transfers[line].index;
1150 subIndex = d->transfers[line].subIndex;
1151 /* End transmission or requesting next segment. */
1152 getSDOlineRestBytes(d, line, &nbBytes);
1154 MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId);
1156 d->transfers[line].state = SDO_FINISHED;
1157 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
1161 /* more than one request to send */
1162 /* code to send the next segment. (cs = 0; c = 0) */
1163 sdo.nodeId = nodeId; /** The server node Id; */
1164 sdo.body.data[0] = (d->transfers[line].toggle << 4);
1165 err = lineToSDO(d, line, 7, sdo.body.data + 1);
1167 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1173 /* code to send the last segment. (cs = 0; c = 1) */
1174 sdo.nodeId = nodeId; /* The server node Id; */
1175 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
1176 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
1178 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1181 for (i = nbBytes + 1 ; i < 8 ; i++)
1182 sdo.body.data[i] = 0;
1184 MSG_WAR(0x3AA7, "SDO sending download segment to nodeId", nodeId);
1185 sendSDO(d, whoami, sdo);
1187 } /* end if I am a CLIENT */
1191 abortCode = (*m).data[3] |
1192 ((UNS32)m->data[5] << 8) |
1193 ((UNS32)m->data[6] << 16) |
1194 ((UNS32)m->data[7] << 24);
1195 /* Received SDO abort. */
1196 /* Looking for the line concerned. */
1197 if (whoami == SDO_SERVER) {
1198 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1200 resetSDOline( d, line );
1201 MSG_WAR(0x3AA8, "SD0. Received SDO abort. Line released. Code : ", abortCode);
1204 MSG_WAR(0x3AA9, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1205 /* Tips : The end user has no way to know that the server node has received an abort SDO. */
1206 /* Its is ok, I think.*/
1208 else { /* If I am CLIENT */
1209 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1211 /* The line *must* be released by the core program. */
1213 d->transfers[line].state = SDO_ABORTED_RCV;
1214 d->transfers[line].abortCode = abortCode;
1215 MSG_WAR(0x3AB0, "SD0. Received SDO abort. Line state ABORTED. Code : ", abortCode);
1216 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
1219 MSG_WAR(0x3AB1, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1223 /* Error : Unknown cs */
1224 MSG_ERR(0x1AB2, "SDO. Received unknown command specifier : ", getSDOcs(m->data[0]));
1246 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1247 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize)
1252 s_SDO sdo; /* SDO to transmit */
1256 UNS8 *pNodeIdServer;
1259 MSG_WAR(0x3AC0, "Send SDO to write in the dictionary of node : ", nodeId);
1260 MSG_WAR(0x3AC1, " At index : ", index);
1261 MSG_WAR(0x3AC2, " subIndex : ", subIndex);
1262 MSG_WAR(0x3AC3, " nb bytes : ", count);
1264 /* Verify that there is no SDO communication yet. */
1265 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1267 MSG_ERR(0x1AC4, "SDO error : Communication yet established. with node : ", nodeId);
1270 /* Taking the line ... */
1271 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1273 MSG_ERR(0x1AC5, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1276 /* Check which SDO to use to communicate with the node */
1277 offset = d->firstIndex->SDO_CLT;
1278 lastIndex = d->lastIndex->SDO_CLT;
1280 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
1284 while (offset <= lastIndex) {
1285 if (d->objdict[offset].bSubCount <= 3) {
1286 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
1289 /* looking for the nodeId server */
1290 pNodeIdServer = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
1291 nodeIdServer = *pNodeIdServer;
1292 MSG_WAR(0x1AD2, "index : ", 0x1280 + i);
1293 MSG_WAR(0x1AD3, "nodeIdServer : ", nodeIdServer);
1295 if(nodeIdServer == nodeId) {
1303 MSG_ERR(0x1AC9, "SDO. Error. No client found to communicate with node : ", nodeId);
1306 MSG_WAR(0x3AD0," SDO client defined at index : ", 0x1280 + i);
1307 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
1308 d->transfers[line].count = count;
1309 d->transfers[line].dataType = dataType;
1311 /* Copy data to transfers structure. */
1312 for (j = 0 ; j < count ; j++) {
1313 # ifdef CANOPEN_BIG_ENDIAN
1314 if (dataType == 0 && endianize)
1315 d->transfers[line].data[count - 1 - j] = ((char *)data)[j];
1316 else /* String of bytes. */
1317 d->transfers[line].data[j] = ((char *)data)[j];
1319 d->transfers[line].data[j] = ((char *)data)[j];
1322 /* Send the SDO to the server. Initiate download, cs=1. */
1323 sdo.nodeId = nodeId;
1324 if (count <= 4) { /* Expedited transfert */
1325 sdo.body.data[0] = (1 << 5) | ((4 - count) << 2) | 3;
1326 for (i = 4 ; i < 8 ; i++)
1327 sdo.body.data[i] = d->transfers[line].data[i - 4];
1328 d->transfers[line].offset = count;
1330 else { /** Normal transfert */
1331 sdo.body.data[0] = (1 << 5) | 1;
1332 sdo.body.data[4] = count; /* nb of byte to transmit. Max = 255. (canfestival2 limitation). */
1333 for (i = 5 ; i < 8 ; i++)
1334 sdo.body.data[i] = 0;
1336 sdo.body.data[1] = index & 0xFF; /* LSB */
1337 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1338 sdo.body.data[3] = subIndex;
1340 d->transfers[line].Callback = Callback;
1342 err = sendSDO(d, SDO_CLIENT, sdo);
1344 MSG_ERR(0x1AD1, "SDO. Error while sending SDO to node : ", nodeId);
1345 /* release the line */
1346 resetSDOline(d, line);
1367 UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1368 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data)
1370 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, NULL, 1);
1387 UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index,
1388 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback)
1390 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback, 1);
1405 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1411 s_SDO sdo; /* SDO to transmit */
1412 UNS8 *pNodeIdServer;
1416 MSG_WAR(0x3AD5, "Send SDO to read in the dictionary of node : ", nodeId);
1417 MSG_WAR(0x3AD6, " At index : ", index);
1418 MSG_WAR(0x3AD7, " subIndex : ", subIndex);
1421 /* Verify that there is no SDO communication yet. */
1422 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1424 MSG_ERR(0x1AD8, "SDO error : Communication yet established. with node : ", nodeId);
1427 /* Taking the line ... */
1428 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1430 MSG_ERR(0x1AD9, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1434 MSG_WAR(0x3AE0, "Transmission on line : ", line);
1436 /* Check which SDO to use to communicate with the node */
1437 offset = d->firstIndex->SDO_CLT;
1438 lastIndex = d->lastIndex->SDO_CLT;
1440 MSG_ERR(0x1AE1, "writeNetworkDict : No SDO client index found", 0);
1444 while (offset <= lastIndex) {
1445 if (d->objdict[offset].bSubCount <= 3) {
1446 MSG_ERR(0x1AE2, "Subindex 3 not found at index ", 0x1280 + i);
1449 /* looking for the nodeId server */
1450 pNodeIdServer = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
1451 nodeIdServer = *pNodeIdServer;
1453 if(nodeIdServer == nodeId) {
1461 MSG_ERR(0x1AE3, "SDO. Error. No client found to communicate with node : ", nodeId);
1464 MSG_WAR(0x3AE4," SDO client defined at index : ", 0x1280 + i);
1465 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
1466 getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1467 sdo.nodeId = nodeId;
1468 /* Send the SDO to the server. Initiate upload, cs=2. */
1469 d->transfers[line].dataType = dataType;
1470 sdo.body.data[0] = (2 << 5);
1471 sdo.body.data[1] = index & 0xFF; /* LSB */
1472 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1473 sdo.body.data[3] = subIndex;
1474 for (i = 4 ; i < 8 ; i++)
1475 sdo.body.data[i] = 0;
1476 d->transfers[line].Callback = Callback;
1477 err = sendSDO(d, SDO_CLIENT, sdo);
1479 MSG_ERR(0x1AE5, "SDO. Error while sending SDO to node : ", nodeId);
1480 /* release the line */
1481 resetSDOline(d, line);
1498 UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType)
1500 return _readNetworkDict (d, nodeId, index, subIndex, dataType, NULL);
1515 UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1517 return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
1531 UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size,
1539 /* Looking for the line tranfert. */
1540 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1542 MSG_ERR(0x1AF0, "SDO error : No line found for communication with node : ", nodeId);
1543 return SDO_ABORTED_INTERNAL;
1545 if (d->transfers[line].state != SDO_FINISHED)
1546 return d->transfers[line].state;
1548 /* Transfert is finished. Put the value in the data. */
1549 * size = (UNS8)d->transfers[line].count;
1550 for ( i = 0 ; i < *size ; i++) {
1551 # ifdef CANOPEN_BIG_ENDIAN
1552 if (d->transfers[line].dataType != visible_string)
1553 ( (char *) data)[*size - 1 - i] = d->transfers[line].data[i];
1554 else /* String of bytes. */
1555 ( (char *) data)[i] = d->transfers[line].data[i];
1557 ( (char *) data)[i] = d->transfers[line].data[i];
1560 return SDO_FINISHED;
1572 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode)
1578 /* Looking for the line tranfert. */
1579 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1581 MSG_ERR(0x1AF1, "SDO error : No line found for communication with node : ", nodeId);
1582 return SDO_ABORTED_INTERNAL;
1584 * abortCode = d->transfers[line].abortCode;
1585 return d->transfers[line].state;