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 */
38 /* Uncomment if your compiler does not support inline functions */
47 /*Internals prototypes*/
50 ** Called by writeNetworkDict
64 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
65 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize);
68 ** Called by readNetworkDict
79 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex,
80 UNS8 dataType, SDOCallback_t Callback);
83 /***************************************************************************/
84 /* SDO (un)packing macros */
86 /** Returns the command specifier (cs, ccs, scs) from the first byte of the SDO
88 #define getSDOcs(byte) (byte >> 5)
90 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 2 bits
92 #define getSDOn2(byte) ((byte >> 2) & 3)
94 /** Returns the number of bytes without data from the first byte of the SDO. Coded in 3 bits
96 #define getSDOn3(byte) ((byte >> 1) & 7)
98 /** Returns the transfer type from the first byte of the SDO
100 #define getSDOe(byte) ((byte >> 1) & 1)
102 /** Returns the size indicator from the first byte of the SDO
104 #define getSDOs(byte) (byte & 1)
106 /** Returns the indicator of end transmission from the first byte of the SDO
108 #define getSDOc(byte) (byte & 1)
110 /** Returns the toggle from the first byte of the SDO
112 #define getSDOt(byte) ((byte >> 4) & 1)
114 /** Returns the index from the bytes 1 and 2 of the SDO
116 #define getSDOindex(byte1, byte2) ((byte2 << 8) | (byte1))
118 /** Returns the subIndex from the byte 3 of the SDO
120 #define getSDOsubIndex(byte3) (byte3)
128 void SDOTimeoutAlarm(CO_Data* d, UNS32 id)
130 MSG_ERR(0x1A01, "SDO timeout. SDO response not received.", 0);
131 MSG_WAR(0x2A02, "server node : ", d->transfers[id].nodeId);
132 MSG_WAR(0x2A02, " index : ", d->transfers[id].index);
133 MSG_WAR(0x2A02, " subIndex : ", d->transfers[id].subIndex);
134 /* Reset timer handler */
135 d->transfers[id].timer = TIMER_NONE;
136 /*Set aborted state*/
137 d->transfers[id].state = SDO_ABORTED_INTERNAL;
138 /* Sending a SDO abort */
139 sendSDOabort(d, d->transfers[id].whoami,
140 d->transfers[id].index, d->transfers[id].subIndex, SDOABT_TIMED_OUT);
141 d->transfers[id].abortCode = SDOABT_TIMED_OUT;
142 /* Call the user function to inform of the problem.*/
143 if(d->transfers[id].Callback)
144 /*If ther is a callback, it is responsible to close SDO transfer (client)*/
145 (*d->transfers[id].Callback)(d,d->transfers[id].nodeId);
146 else if(d->transfers[id].whoami == SDO_SERVER)
147 /*Else, if server, reset the line*/
148 resetSDOline(d, (UNS8)id);
151 #define StopSDO_TIMER(id) \
152 MSG_WAR(0x3A05, "StopSDO_TIMER for line : ", line);\
153 d->transfers[id].timer = DelAlarm(d->transfers[id].timer);
155 #define StartSDO_TIMER(id) \
156 MSG_WAR(0x3A06, "StartSDO_TIMER for line : ", line);\
157 d->transfers[id].timer = SetAlarm(d,id,&SDOTimeoutAlarm,MS_TO_TIMEVAL(SDO_TIMEOUT_MS),0);
159 #define RestartSDO_TIMER(id) \
160 MSG_WAR(0x3A07, "restartSDO_TIMER for line : ", line);\
161 if(d->transfers[id].timer != TIMER_NONE) { StopSDO_TIMER(id) StartSDO_TIMER(id) }
164 ** Reset all sdo buffers
168 void resetSDO (CO_Data* d)
172 /* transfer structure initialization */
173 for (j = 0 ; j < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; j++)
185 UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line)
189 MSG_WAR(0x3A08, "Enter in SDOlineToObjdict ", line);
190 size = (UNS8)d->transfers[line].count;
191 errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
192 (void *) d->transfers[line].data, &size, 1);
193 if (errorCode != OD_SUCCESSFUL)
195 MSG_WAR(0x3A08, "exit of SDOlineToObjdict ", line);
208 UNS32 objdictToSDOline (CO_Data* d, UNS8 line)
214 MSG_WAR(0x3A05, "objdict->line index : ", d->transfers[line].index);
215 MSG_WAR(0x3A06, " subIndex : ", d->transfers[line].subIndex);
217 errorCode = getODentry(d, d->transfers[line].index,
218 d->transfers[line].subIndex,
219 (void *)d->transfers[line].data,
220 &size, &dataType, 0);
222 if (errorCode != OD_SUCCESSFUL)
225 d->transfers[line].count = size;
226 d->transfers[line].offset = 0;
228 /*Me laisser a, please ! (FD)*/
231 for (i = 0 ; i < 10 ; i++) {
232 MSG_WAR(i, "data= ", d->transfers[line].data[i]);
249 UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data) {
253 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
254 MSG_ERR(0x1A10,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
257 if ((d->transfers[line].offset + nbBytes) > d->transfers[line].count) {
258 MSG_ERR(0x1A11,"SDO Size of data too large. Exceed count", nbBytes);
261 offset = (UNS8)d->transfers[line].offset;
262 for (i = 0 ; i < nbBytes ; i++)
263 * (data + i) = d->transfers[line].data[offset + i];
264 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
278 UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data)
283 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
284 MSG_ERR(0x1A15,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
287 offset = (UNS8)d->transfers[line].offset;
288 for (i = 0 ; i < nbBytes ; i++)
289 d->transfers[line].data[offset + i] = * (data + i);
290 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
306 UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index,
307 UNS8 subIndex, UNS32 abortCode)
311 err = getSDOlineOnUse( d, nodeId, whoami, &line );
312 if (!err) /* If a line on use have been found.*/
313 MSG_WAR(0x3A20, "FailedSDO : line found : ", line);
314 if ((! err) && (whoami == SDO_SERVER)) {
315 resetSDOline( d, line );
316 MSG_WAR(0x3A21, "FailedSDO : line released : ", line);
318 if ((! err) && (whoami == SDO_CLIENT)) {
320 d->transfers[line].state = SDO_ABORTED_INTERNAL;
322 MSG_WAR(0x3A22, "Sending SDO abort ", 0);
323 err = sendSDOabort(d, whoami, index, subIndex, abortCode);
325 MSG_WAR(0x3A23, "Unable to send the SDO abort", 0);
337 void resetSDOline ( CO_Data* d, UNS8 line )
340 MSG_WAR(0x3A25, "reset SDO line nb : ", line);
341 initSDOline(d, line, 0, 0, 0, SDO_RESET);
342 for (i = 0 ; i < SDO_MAX_LENGTH_TRANSFERT ; i++)
343 d->transfers[line].data[i] = 0;
358 UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state)
360 MSG_WAR(0x3A25, "init SDO line nb : ", line);
361 if (state == SDO_DOWNLOAD_IN_PROGRESS || state == SDO_UPLOAD_IN_PROGRESS){
366 d->transfers[line].nodeId = nodeId;
367 d->transfers[line].index = index;
368 d->transfers[line].subIndex = subIndex;
369 d->transfers[line].state = state;
370 d->transfers[line].toggle = 0;
371 d->transfers[line].count = 0;
372 d->transfers[line].offset = 0;
373 d->transfers[line].dataType = 0;
374 d->transfers[line].Callback = NULL;
387 UNS8 getSDOfreeLine ( CO_Data* d, UNS8 whoami, UNS8 *line )
392 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
393 if ( d->transfers[i].state == SDO_RESET ) {
395 d->transfers[i].whoami = whoami;
399 MSG_ERR(0x1A25, "Too many SDO in progress. Aborted.", i);
413 UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line)
418 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
419 if ( (d->transfers[i].state != SDO_RESET) &&
420 (d->transfers[i].nodeId == nodeId) &&
421 (d->transfers[i].whoami == whoami) ) {
438 UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami)
442 err = getSDOlineOnUse(d, nodeId, whoami, &line);
444 MSG_WAR(0x2A30, "No SDO communication to close for node : ", nodeId);
447 resetSDOline(d, line);
460 UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 * nbBytes)
462 if (d->transfers[line].count == 0) /* if received initiate SDO protocol with e=0 and s=0 */
465 * nbBytes = (UNS8)d->transfers[line].count - (UNS8)d->transfers[line].offset;
478 UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 nbBytes)
480 if (nbBytes > SDO_MAX_LENGTH_TRANSFERT) {
481 MSG_ERR(0x1A35,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
484 d->transfers[line].count = nbBytes;
497 UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo)
504 UNS16 * pwCobId = NULL;
505 UNS8 * pwNodeId = NULL;
507 MSG_WAR(0x3A38, "sendSDO",0);
508 if( !((d->nodeState == Operational) || (d->nodeState == Pre_operational ))) {
509 MSG_WAR(0x2A39, "unable to send the SDO (not in op or pre-op mode", d->nodeState);
513 /*get the server->client cobid*/
514 if ( whoami == SDO_SERVER ) {/*case server. Easy because today only one server SDO is authorized in CanFestival*/
515 offset = d->firstIndex->SDO_SVR;
517 MSG_ERR(0x1A42, "SendSDO : No SDO server found", 0);
520 pwCobId = (UNS16*) d->objdict[offset].pSubindex[2].pObject;
521 MSG_WAR(0x3A41, "I am server. cobId : ", *pwCobId);
523 else { /*case client*/
524 /* Get the client->server cobid.*/
526 offset = d->firstIndex->SDO_CLT;
527 lastIndex = d->lastIndex->SDO_CLT;
529 MSG_ERR(0x1A42, "SendSDO : No SDO client index found", 0);
532 /* First, have to find at the index where is defined the communication with the server node */
533 while (offset <= lastIndex){
534 MSG_WAR(0x3A43,"Reading index : ", 0x1280 + sdoNum);
535 if (d->objdict[offset].bSubCount <= 3) {
536 MSG_ERR(0x1A28, "Subindex 3 not found at index ", 0x1280 + sdoNum);
539 pwNodeId = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
540 MSG_WAR(0x3A44, "Found nodeId server = ", *pwNodeId);
541 if(*pwNodeId == sdo.nodeId) {
549 MSG_WAR (0x2A45, "No SDO client corresponds to the mesage to send to node ", sdo.nodeId);
552 /* Second, read the cobid client->server */
553 pwCobId = (UNS16*) d->objdict[offset].pSubindex[1].pObject;
555 /* message copy for sending */
557 m.rtr = NOT_A_REQUEST;
558 /* the length of SDO must be 8 */
560 for (i = 0 ; i < 8 ; i++) {
561 m.data[i] = sdo.body.data[i];
563 return canSend(d->canHandle,&m);
577 UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS16 index, UNS8 subIndex, UNS32 abortCode)
581 MSG_WAR(0x2A50,"Sending SDO abort ", abortCode);
582 sdo.nodeId = *d->bDeviceNodeId;
583 sdo.body.data[0] = 0x80;
585 sdo.body.data[1] = index & 0xFF; /* LSB */
586 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
588 sdo.body.data[3] = subIndex;
590 sdo.body.data[4] = (UNS8)(abortCode & 0xFF);
591 sdo.body.data[5] = (UNS8)((abortCode >> 8) & 0xFF);
592 sdo.body.data[6] = (UNS8)((abortCode >> 16) & 0xFF);
593 sdo.body.data[7] = (UNS8)((abortCode >> 24) & 0xFF);
594 ret = sendSDO(d, whoami, sdo);
607 UNS8 proceedSDO (CO_Data* d, Message *m)
611 UNS8 nbBytes; /* received or to be transmited. */
612 UNS8 nodeId = 0; /* The node from which the SDO is received */
613 UNS8 *pNodeId = NULL;
614 UNS8 whoami = SDO_UNKNOWN; /* SDO_SERVER or SDO_CLIENT.*/
615 UNS32 errorCode; /* while reading or writing in the local object dictionary.*/
616 s_SDO sdo; /* SDO to transmit */
621 UNS16 *pCobId = NULL;
625 MSG_WAR(0x3A60, "proceedSDO ", 0);
626 whoami = SDO_UNKNOWN;
627 /* Looking for the cobId in the object dictionary. */
628 /* Am-I a server ? */
629 offset = d->firstIndex->SDO_SVR;
630 lastIndex = d->lastIndex->SDO_SVR;
632 if(offset) while (offset <= lastIndex) {
633 if (d->objdict[offset].bSubCount <= 1) {
634 MSG_ERR(0x1A61, "Subindex 1 not found at index ", 0x1200 + j);
637 pCobId = (UNS16*) d->objdict[offset].pSubindex[1].pObject;
638 if ( *pCobId == (*m).cob_id ) {
640 MSG_WAR(0x3A62, "proceedSDO. I am server. index : ", 0x1200 + j);
641 /* In case of server, the node id of the client may be unknown. So we put the index minus offset */
642 /* 0x1200 where the cobid received is defined. */
649 if (whoami == SDO_UNKNOWN) {
651 offset = d->firstIndex->SDO_CLT;
652 lastIndex = d->lastIndex->SDO_CLT;
654 if(offset) while (offset <= lastIndex) {
655 if (d->objdict[offset].bSubCount <= 3) {
656 MSG_ERR(0x1A63, "Subindex 3 not found at index ", 0x1280 + j);
659 /* a) Looking for the cobid received. */
660 pCobId = (UNS16*) d->objdict[offset].pSubindex[2].pObject;
661 if (*pCobId == (*m).cob_id ) {
662 /* b) cobid found, so reading the node id of the server. */
663 pNodeId = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
666 MSG_WAR(0x3A64, "proceedSDO. I am server. index : ", 0x1280 + j);
667 MSG_WAR(0x3A65, " Server nodeId : ", nodeId);
674 if (whoami == SDO_UNKNOWN) {
675 return 0xFF;/* This SDO was not for us ! */
678 /* Test if the size of the SDO is ok */
679 if ( (*m).len != 8) {
680 MSG_ERR(0x1A67, "Error size SDO. CobId : ", (*m).cob_id);
681 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_GENERAL_ERROR);
685 if (whoami == SDO_CLIENT) {
686 MSG_WAR(0x3A68, "I am CLIENT. Received SDO from nodeId : ", nodeId);
689 MSG_WAR(0x3A69, "I am SERVER. Received SDO cobId : ", (*m).cob_id);
692 /* Testing the command specifier */
693 /* Allowed : cs = 0, 1, 2, 3, 4. (= all except those for block tranfert). */
694 /* cs = other : Not allowed -> abort. */
695 switch (getSDOcs(m->data[0])) {
699 if (whoami == SDO_SERVER) {
700 /* Receiving a download segment data. */
701 /* A SDO transfert should have been yet initiated. */
702 err = getSDOlineOnUse( d, nodeId, whoami, &line );
704 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
706 MSG_ERR(0x1A70, "SDO error : Received download segment for unstarted trans. index 0x1200 + ",
708 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
711 /* Reset the wathdog */
712 RestartSDO_TIMER(line)
713 MSG_WAR(0x3A71, "Received SDO download segment defined at index 0x1200 + ", nodeId);
714 index = d->transfers[line].index;
715 subIndex = d->transfers[line].subIndex;
717 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
718 MSG_ERR(0x1A72, "SDO error : Toggle error : ", getSDOt(m->data[0]));
719 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
722 /* Nb of data to be downloaded */
723 nbBytes = 7 - getSDOn3(m->data[0]);
724 /* Store the data in the transfert structure. */
725 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
727 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
730 /* Sending the SDO response, CS = 1 */
731 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender). */
732 sdo.body.data[0] = (1 << 5) | (d->transfers[line].toggle << 4);
733 for (i = 1 ; i < 8 ; i++)
734 sdo.body.data[i] = 0;
735 MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", nodeId);
736 sendSDO(d, whoami, sdo);
737 /* Inverting the toggle for the next segment. */
738 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
739 /* If it was the last segment, */
740 if (getSDOc(m->data[0])) {
741 /* Transfering line data to object dictionary. */
742 /* The code does not use the "d" of initiate frame. So it is safe if e=s=0 */
743 errorCode = SDOlineToObjdict(d, line);
745 MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0);
746 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
749 /* Release of the line */
750 resetSDOline(d, line);
751 MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", nodeId);
753 } /* end if SERVER */
754 else { /* if CLIENT */
756 /* It is a request for a previous upload segment. We should find a line opened for this.*/
757 err = getSDOlineOnUse( d, nodeId, whoami, &line);
759 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
761 MSG_ERR(0x1A75, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
762 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
765 /* Reset the wathdog */
766 RestartSDO_TIMER(line)
767 index = d->transfers[line].index;
768 subIndex = d->transfers[line].subIndex;
769 /* test of the toggle; */
770 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
771 MSG_ERR(0x1A76, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
772 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
775 /* nb of data to be uploaded */
776 nbBytes = 7 - getSDOn3(m->data[0]);
777 /* Storing the data in the line structure. */
778 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
780 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
783 /* Inverting the toggle for the next segment. */
784 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
785 /* If it was the last segment,*/
786 if ( getSDOc(m->data[0])) {
787 /* Put in state finished */
788 /* The code is safe for the case e=s=0 in initiate frame. */
790 d->transfers[line].state = SDO_FINISHED;
791 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
793 MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId);
795 else { /* more segments to receive */
796 /* Sending the request for the next segment. */
798 sdo.body.data[0] = (3 << 5) | (d->transfers[line].toggle << 4);
799 for (i = 1 ; i < 8 ; i++)
800 sdo.body.data[i] = 0;
801 sendSDO(d, whoami, sdo);
802 MSG_WAR(0x3A78, "SDO send upload segment request to nodeId", nodeId);
804 } /* End if CLIENT */
809 /* Receive of an initiate download */
810 if (whoami == SDO_SERVER) {
811 index = getSDOindex(m->data[1],m->data[2]);
812 subIndex = getSDOsubIndex(m->data[3]);
813 MSG_WAR(0x3A79, "Received SDO Initiate Download (to store data) defined at index 0x1200 + ",
815 MSG_WAR(0x3A80, "Writing at index : ", index);
816 MSG_WAR(0x3A80, "Writing at subIndex : ", subIndex);
818 /* Search if a SDO transfert have been yet initiated */
819 err = getSDOlineOnUse( d, nodeId, whoami, &line );
821 MSG_ERR(0x1A81, "SDO error : Transmission yet started.", 0);
822 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
825 /* No line on use. Great ! */
826 /* Try to open a new line. */
827 err = getSDOfreeLine( d, whoami, &line );
829 MSG_ERR(0x1A82, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
830 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
833 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
835 if (getSDOe(m->data[0])) { /* If SDO expedited */
836 /* nb of data to be downloaded */
837 nbBytes = 4 - getSDOn2(m->data[0]);
838 /* Storing the data in the line structure. */
839 d->transfers[line].count = nbBytes;
840 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
843 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
847 /* SDO expedited -> transfert finished. Data can be stored in the dictionary. */
848 /*The line will be reseted when it is downloading in the dictionary. */
849 MSG_WAR(0x3A83, "SDO Initiate Download is an expedited transfert. Finished.: ", nodeId);
850 /* Transfering line data to object dictionary. */
851 errorCode = SDOlineToObjdict(d, line);
853 MSG_ERR(0x1A84, "SDO error : Unable to copy the data in the object dictionary", 0);
854 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
857 /* Release of the line. */
858 resetSDOline(d, line);
860 else {/* So, if it is not an expedited transfert */
861 if (getSDOs(m->data[0])) {
862 /* TODO : if e and s = 0, not reading m->data[4] but put nbBytes = 0 */
863 nbBytes = m->data[4]; /* Transfert limited to 255 bytes. */
864 err = setSDOlineRestBytes(d, nodeId, nbBytes);
866 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
871 /*Sending a SDO, cs=3*/
872 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender).*/
873 sdo.body.data[0] = 3 << 5;
874 sdo.body.data[1] = index & 0xFF; /* LSB */
875 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
876 sdo.body.data[3] = subIndex;
877 for (i = 4 ; i < 8 ; i++)
878 sdo.body.data[i] = 0;
879 sendSDO(d, whoami, sdo);
880 } /* end if I am SERVER */
883 /* It is a response for a previous download segment. We should find a line opened for this. */
884 err = getSDOlineOnUse( d, nodeId, whoami, &line);
886 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
888 MSG_ERR(0x1A85, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
889 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
892 /* Reset the wathdog */
893 RestartSDO_TIMER(line)
894 index = d->transfers[line].index;
895 subIndex = d->transfers[line].subIndex;
896 /* test of the toggle; */
897 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
898 MSG_ERR(0x1A86, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
899 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
903 /* End transmission or downloading next segment. We need to know if it will be the last one. */
904 getSDOlineRestBytes(d, line, &nbBytes);
906 MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId);
908 d->transfers[line].state = SDO_FINISHED;
909 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
912 /* At least one transfer to send. */
914 /* several segments to download.*/
915 /* code to send the next segment. (cs = 0; c = 0) */
916 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
917 sdo.nodeId = nodeId; /* The server node Id; */
918 sdo.body.data[0] = (d->transfers[line].toggle << 4);
919 err = lineToSDO(d, line, 7, sdo.body.data + 1);
921 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
927 /* code to send the last segment. (cs = 0; c = 1)*/
928 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
929 sdo.nodeId = nodeId; /* The server node Id; */
930 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
931 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
933 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
936 for (i = nbBytes + 1 ; i < 8 ; i++)
937 sdo.body.data[i] = 0;
939 MSG_WAR(0x3A88, "SDO sending download segment to nodeId", nodeId);
940 sendSDO(d, whoami, sdo);
941 } /* end if I am a CLIENT */
946 /* Receive of an initiate upload.*/
947 if (whoami == SDO_SERVER) {
948 index = getSDOindex(m->data[1],m->data[2]);
949 subIndex = getSDOsubIndex(m->data[3]);
950 MSG_WAR(0x3A89, "Received SDO Initiate upload (to send data) defined at index 0x1200 + ",
952 MSG_WAR(0x3A90, "Reading at index : ", index);
953 MSG_WAR(0x3A91, "Reading at subIndex : ", subIndex);
954 /* Search if a SDO transfert have been yet initiated*/
955 err = getSDOlineOnUse( d, nodeId, whoami, &line );
957 MSG_ERR(0x1A92, "SDO error : Transmission yet started at line : ", line);
958 MSG_WAR(0x3A93, "nodeId = ", nodeId);
959 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
962 /* No line on use. Great !*/
963 /* Try to open a new line.*/
964 err = getSDOfreeLine( d, whoami, &line );
966 MSG_ERR(0x1A71, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
967 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
970 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
971 /* Transfer data from dictionary to the line structure. */
972 errorCode = objdictToSDOline(d, line);
975 MSG_ERR(0x1A94, "SDO error : Unable to copy the data from object dictionary. Err code : ",
977 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
980 /* Preparing the response.*/
981 getSDOlineRestBytes(d, line, &nbBytes); /* Nb bytes to transfer ? */
982 sdo.nodeId = nodeId; /* The server node Id; */
984 /* normal transfert. (segmented). */
985 /* code to send the initiate upload response. (cs = 2) */
986 sdo.body.data[0] = (2 << 5) | 1;
987 sdo.body.data[1] = index & 0xFF; /* LSB */
988 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
989 sdo.body.data[3] = subIndex;
990 sdo.body.data[4] = nbBytes; /* Limitation of canfestival2 : Max tranfert is 256 bytes.*/
991 /* It takes too much memory to upgrate to 2^32 because the size of data is also coded */
992 /* in the object dictionary, at every index and subindex. */
993 for (i = 5 ; i < 8 ; i++)
994 sdo.body.data[i] = 0;
995 MSG_WAR(0x3A95, "SDO. Sending normal upload initiate response defined at index 0x1200 + ", nodeId);
996 sendSDO(d, whoami, sdo);
999 /* Expedited upload. (cs = 2 ; e = 1) */
1000 sdo.body.data[0] = (2 << 5) | ((4 - nbBytes) << 2) | 3;
1001 sdo.body.data[1] = index & 0xFF; /* LSB */
1002 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1003 sdo.body.data[3] = subIndex;
1004 err = lineToSDO(d, line, nbBytes, sdo.body.data + 4);
1006 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1009 for (i = 4 + nbBytes ; i < 8 ; i++)
1010 sdo.body.data[i] = 0;
1011 MSG_WAR(0x3A96, "SDO. Sending expedited upload initiate response defined at index 0x1200 + ",
1013 sendSDO(d, whoami, sdo);
1014 /* Release the line.*/
1015 resetSDOline(d, line);
1017 } /* end if I am SERVER*/
1020 /* It is the response for the previous initiate upload request.*/
1021 /* We should find a line opened for this. */
1022 err = getSDOlineOnUse( d, nodeId, whoami, &line);
1024 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
1026 MSG_ERR(0x1A97, "SDO error : Received response for unknown upload request from nodeId", nodeId);
1027 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
1030 /* Reset the wathdog */
1031 RestartSDO_TIMER(line)
1032 index = d->transfers[line].index;
1033 subIndex = d->transfers[line].subIndex;
1035 if (getSDOe(m->data[0])) { /* If SDO expedited */
1036 /* nb of data to be uploaded */
1037 nbBytes = 4 - getSDOn2(m->data[0]);
1038 /* Storing the data in the line structure. */
1039 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
1041 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1044 /* SDO expedited -> transfert finished. data are available via getReadResultNetworkDict(). */
1045 MSG_WAR(0x3A98, "SDO expedited upload finished. Response received from node : ", nodeId);
1047 d->transfers[line].count = nbBytes;
1048 d->transfers[line].state = SDO_FINISHED;
1049 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
1052 else { /* So, if it is not an expedited transfert */
1053 /* Storing the nb of data to receive. */
1054 if (getSDOs(m->data[0])) {
1055 nbBytes = m->data[4]; /* Remember the limitation to 255 bytes to transfert */
1056 err = setSDOlineRestBytes(d, line, nbBytes);
1058 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1062 /* Requesting next segment. (cs = 3) */
1063 sdo.nodeId = nodeId;
1064 sdo.body.data[0] = 3 << 5;
1065 for (i = 1 ; i < 8 ; i++)
1066 sdo.body.data[i] = 0;
1067 MSG_WAR(0x3A99, "SDO. Sending upload segment request to node : ", nodeId);
1068 sendSDO(d, whoami, sdo);
1070 } /* End if CLIENT */
1075 if (whoami == SDO_SERVER) {
1076 /* Receiving a upload segment. */
1077 /* A SDO transfert should have been yet initiated. */
1078 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1080 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
1082 MSG_ERR(0x1AA0, "SDO error : Received upload segment for unstarted trans. index 0x1200 + ",
1084 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
1087 /* Reset the wathdog */
1088 RestartSDO_TIMER(line)
1089 MSG_WAR(0x3AA1, "Received SDO upload segment defined at index 0x1200 + ", nodeId);
1090 index = d->transfers[line].index;
1091 subIndex = d->transfers[line].subIndex;
1093 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
1094 MSG_ERR(0x1AA2, "SDO error : Toggle error : ", getSDOt(m->data[0]));
1095 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
1098 /* Uploading next segment. We need to know if it will be the last one. */
1099 getSDOlineRestBytes(d, line, &nbBytes);
1101 /* The segment to transfer is not the last one.*/
1102 /* code to send the next segment. (cs = 0; c = 0) */
1103 sdo.nodeId = nodeId; /* The server node Id; */
1104 sdo.body.data[0] = (d->transfers[line].toggle << 4);
1105 err = lineToSDO(d, line, 7, sdo.body.data + 1);
1107 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1110 /* Inverting the toggle for the next tranfert. */
1111 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
1112 MSG_WAR(0x3AA3, "SDO. Sending upload segment defined at index 0x1200 + ", nodeId);
1113 sendSDO(d, whoami, sdo);
1117 /* code to send the last segment. (cs = 0; c = 1) */
1118 sdo.nodeId = nodeId; /** The server node Id; */
1119 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
1120 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
1122 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1125 for (i = nbBytes + 1 ; i < 8 ; i++)
1126 sdo.body.data[i] = 0;
1127 MSG_WAR(0x3AA4, "SDO. Sending last upload segment defined at index 0x1200 + ", nodeId);
1128 sendSDO(d, whoami, sdo);
1129 /* Release the line */
1130 resetSDOline(d, line);
1132 } /* end if SERVER*/
1135 /* It is the response for the previous initiate download request. */
1136 /* We should find a line opened for this. */
1137 err = getSDOlineOnUse( d, nodeId, whoami, &line);
1139 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
1141 MSG_ERR(0x1AA5, "SDO error : Received response for unknown download request from nodeId", nodeId);
1142 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
1145 /* Reset the watchdog */
1146 RestartSDO_TIMER(line)
1147 index = d->transfers[line].index;
1148 subIndex = d->transfers[line].subIndex;
1149 /* End transmission or requesting next segment. */
1150 getSDOlineRestBytes(d, line, &nbBytes);
1152 MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId);
1154 d->transfers[line].state = SDO_FINISHED;
1155 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
1159 /* more than one request to send */
1160 /* code to send the next segment. (cs = 0; c = 0) */
1161 sdo.nodeId = nodeId; /** The server node Id; */
1162 sdo.body.data[0] = (d->transfers[line].toggle << 4);
1163 err = lineToSDO(d, line, 7, sdo.body.data + 1);
1165 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1171 /* code to send the last segment. (cs = 0; c = 1) */
1172 sdo.nodeId = nodeId; /* The server node Id; */
1173 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
1174 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
1176 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1179 for (i = nbBytes + 1 ; i < 8 ; i++)
1180 sdo.body.data[i] = 0;
1182 MSG_WAR(0x3AA7, "SDO sending download segment to nodeId", nodeId);
1183 sendSDO(d, whoami, sdo);
1185 } /* end if I am a CLIENT */
1189 abortCode = (*m).data[3] |
1190 ((UNS32)m->data[5] << 8) |
1191 ((UNS32)m->data[6] << 16) |
1192 ((UNS32)m->data[7] << 24);
1193 /* Received SDO abort. */
1194 /* Looking for the line concerned. */
1195 if (whoami == SDO_SERVER) {
1196 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1198 resetSDOline( d, line );
1199 MSG_WAR(0x3AA8, "SD0. Received SDO abort. Line released. Code : ", abortCode);
1202 MSG_WAR(0x3AA9, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1203 /* Tips : The end user has no way to know that the server node has received an abort SDO. */
1204 /* Its is ok, I think.*/
1206 else { /* If I am CLIENT */
1207 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1209 /* The line *must* be released by the core program. */
1211 d->transfers[line].state = SDO_ABORTED_RCV;
1212 d->transfers[line].abortCode = abortCode;
1213 MSG_WAR(0x3AB0, "SD0. Received SDO abort. Line state ABORTED. Code : ", abortCode);
1214 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
1217 MSG_WAR(0x3AB1, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1221 /* Error : Unknown cs */
1222 MSG_ERR(0x1AB2, "SDO. Received unknown command specifier : ", getSDOcs(m->data[0]));
1244 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1245 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize)
1250 s_SDO sdo; /* SDO to transmit */
1254 UNS8 *pNodeIdServer;
1257 MSG_WAR(0x3AC0, "Send SDO to write in the dictionary of node : ", nodeId);
1258 MSG_WAR(0x3AC1, " At index : ", index);
1259 MSG_WAR(0x3AC2, " subIndex : ", subIndex);
1260 MSG_WAR(0x3AC3, " nb bytes : ", count);
1262 /* Verify that there is no SDO communication yet. */
1263 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1265 MSG_ERR(0x1AC4, "SDO error : Communication yet established. with node : ", nodeId);
1268 /* Taking the line ... */
1269 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1271 MSG_ERR(0x1AC5, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1274 /* Check which SDO to use to communicate with the node */
1275 offset = d->firstIndex->SDO_CLT;
1276 lastIndex = d->lastIndex->SDO_CLT;
1278 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
1282 while (offset <= lastIndex) {
1283 if (d->objdict[offset].bSubCount <= 3) {
1284 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
1287 /* looking for the nodeId server */
1288 pNodeIdServer = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
1289 nodeIdServer = *pNodeIdServer;
1290 MSG_WAR(0x1AD2, "index : ", 0x1280 + i);
1291 MSG_WAR(0x1AD3, "nodeIdServer : ", nodeIdServer);
1293 if(nodeIdServer == nodeId) {
1301 MSG_ERR(0x1AC9, "SDO. Error. No client found to communicate with node : ", nodeId);
1304 MSG_WAR(0x3AD0," SDO client defined at index : ", 0x1280 + i);
1305 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
1306 d->transfers[line].count = count;
1307 d->transfers[line].dataType = dataType;
1309 /* Copy data to transfers structure. */
1310 for (j = 0 ; j < count ; j++) {
1311 # ifdef CANOPEN_BIG_ENDIAN
1312 if (dataType == 0 && endianize)
1313 d->transfers[line].data[count - 1 - j] = ((char *)data)[j];
1314 else /* String of bytes. */
1315 d->transfers[line].data[j] = ((char *)data)[j];
1317 d->transfers[line].data[j] = ((char *)data)[j];
1320 /* Send the SDO to the server. Initiate download, cs=1. */
1321 sdo.nodeId = nodeId;
1322 if (count <= 4) { /* Expedited transfert */
1323 sdo.body.data[0] = (1 << 5) | ((4 - count) << 2) | 3;
1324 for (i = 4 ; i < 8 ; i++)
1325 sdo.body.data[i] = d->transfers[line].data[i - 4];
1326 d->transfers[line].offset = count;
1328 else { /** Normal transfert */
1329 sdo.body.data[0] = (1 << 5) | 1;
1330 sdo.body.data[4] = count; /* nb of byte to transmit. Max = 255. (canfestival2 limitation). */
1331 for (i = 5 ; i < 8 ; i++)
1332 sdo.body.data[i] = 0;
1334 sdo.body.data[1] = index & 0xFF; /* LSB */
1335 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1336 sdo.body.data[3] = subIndex;
1338 d->transfers[line].Callback = Callback;
1340 err = sendSDO(d, SDO_CLIENT, sdo);
1342 MSG_ERR(0x1AD1, "SDO. Error while sending SDO to node : ", nodeId);
1343 /* release the line */
1344 resetSDOline(d, line);
1365 UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1366 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data)
1368 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, NULL, 1);
1385 UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index,
1386 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback)
1388 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback, 1);
1403 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1409 s_SDO sdo; /* SDO to transmit */
1410 UNS8 *pNodeIdServer;
1414 MSG_WAR(0x3AD5, "Send SDO to read in the dictionary of node : ", nodeId);
1415 MSG_WAR(0x3AD6, " At index : ", index);
1416 MSG_WAR(0x3AD7, " subIndex : ", subIndex);
1419 /* Verify that there is no SDO communication yet. */
1420 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1422 MSG_ERR(0x1AD8, "SDO error : Communication yet established. with node : ", nodeId);
1425 /* Taking the line ... */
1426 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1428 MSG_ERR(0x1AD9, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1432 MSG_WAR(0x3AE0, "Transmission on line : ", line);
1434 /* Check which SDO to use to communicate with the node */
1435 offset = d->firstIndex->SDO_CLT;
1436 lastIndex = d->lastIndex->SDO_CLT;
1438 MSG_ERR(0x1AE1, "writeNetworkDict : No SDO client index found", 0);
1442 while (offset <= lastIndex) {
1443 if (d->objdict[offset].bSubCount <= 3) {
1444 MSG_ERR(0x1AE2, "Subindex 3 not found at index ", 0x1280 + i);
1447 /* looking for the nodeId server */
1448 pNodeIdServer = (UNS8*) d->objdict[offset].pSubindex[3].pObject;
1449 nodeIdServer = *pNodeIdServer;
1451 if(nodeIdServer == nodeId) {
1459 MSG_ERR(0x1AE3, "SDO. Error. No client found to communicate with node : ", nodeId);
1462 MSG_WAR(0x3AE4," SDO client defined at index : ", 0x1280 + i);
1463 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
1464 getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1465 sdo.nodeId = nodeId;
1466 /* Send the SDO to the server. Initiate upload, cs=2. */
1467 d->transfers[line].dataType = dataType;
1468 sdo.body.data[0] = (2 << 5);
1469 sdo.body.data[1] = index & 0xFF; /* LSB */
1470 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1471 sdo.body.data[3] = subIndex;
1472 for (i = 4 ; i < 8 ; i++)
1473 sdo.body.data[i] = 0;
1474 d->transfers[line].Callback = Callback;
1475 err = sendSDO(d, SDO_CLIENT, sdo);
1477 MSG_ERR(0x1AE5, "SDO. Error while sending SDO to node : ", nodeId);
1478 /* release the line */
1479 resetSDOline(d, line);
1496 UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType)
1498 return _readNetworkDict (d, nodeId, index, subIndex, dataType, NULL);
1513 UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1515 return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
1529 UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size,
1537 /* Looking for the line tranfert. */
1538 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1540 MSG_ERR(0x1AF0, "SDO error : No line found for communication with node : ", nodeId);
1541 return SDO_ABORTED_INTERNAL;
1543 if (d->transfers[line].state != SDO_FINISHED)
1544 return d->transfers[line].state;
1546 /* Transfert is finished. Put the value in the data. */
1547 * size = (UNS8)d->transfers[line].count;
1548 for ( i = 0 ; i < *size ; i++) {
1549 # ifdef CANOPEN_BIG_ENDIAN
1550 if (d->transfers[line].dataType != visible_string)
1551 ( (char *) data)[*size - 1 - i] = d->transfers[line].data[i];
1552 else /* String of bytes. */
1553 ( (char *) data)[i] = d->transfers[line].data[i];
1555 ( (char *) data)[i] = d->transfers[line].data[i];
1558 return SDO_FINISHED;
1570 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode)
1576 /* Looking for the line tranfert. */
1577 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1579 MSG_ERR(0x1AF1, "SDO error : No line found for communication with node : ", nodeId);
1580 return SDO_ABORTED_INTERNAL;
1582 * abortCode = d->transfers[line].abortCode;
1583 return d->transfers[line].state;