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 UNS32 * 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 UNS32 nodeId_32; /* node id in 32 bits, for temporary use */
447 UNS32 *pNodeId = NULL;
448 UNS8 whoami = SDO_UNKNOWN; /* SDO_SERVER or SDO_CLIENT.*/
449 UNS32 errorCode; /* while reading or writing in the local object dictionary.*/
450 s_SDO sdo; /* SDO to transmit */
455 UNS32 * pCobId = NULL;
459 MSG_WAR(0x3A60, "proceedSDO ", 0);
460 whoami = SDO_UNKNOWN;
461 /* Looking for the cobId in the object dictionary. */
462 /* Am-I a server ? */
463 offset = d->firstIndex->SDO_SVR;
464 lastIndex = d->lastIndex->SDO_SVR;
466 if(offset) while (offset <= lastIndex) {
467 if (d->objdict[offset].bSubCount <= 1) {
468 MSG_ERR(0x1A61, "Subindex 1 not found at index ", 0x1200 + j);
471 pCobId = d->objdict[offset].pSubindex[1].pObject;
472 if ( *pCobId == (*m).cob_id.w ) {
474 MSG_WAR(0x3A62, "proceedSDO. I am server. index : ", 0x1200 + j);
475 /* In case of server, the node id of the client may be unknown. So we put the index minus offset */
476 /* 0x1200 where the cobid received is defined. */
483 if (whoami == SDO_UNKNOWN) {
485 offset = d->firstIndex->SDO_CLT;
486 lastIndex = d->lastIndex->SDO_CLT;
488 if(offset) while (offset <= lastIndex) {
489 if (d->objdict[offset].bSubCount <= 3) {
490 MSG_ERR(0x1A63, "Subindex 3 not found at index ", 0x1280 + j);
493 /* a) Looking for the cobid received. */
494 pCobId = d->objdict[offset].pSubindex[2].pObject;
495 if (*pCobId == (*m).cob_id.w ) {
496 /* b) cobid found, so reading the node id of the server. */
497 pNodeId = d->objdict[offset].pSubindex[3].pObject;
499 nodeId_32 = *pNodeId;
500 nodeId = (UNS8)nodeId_32;
501 MSG_WAR(0x3A64, "proceedSDO. I am server. index : ", 0x1280 + j);
502 MSG_WAR(0x3A65, " Server nodeId : ", nodeId);
509 if (whoami == SDO_UNKNOWN) {
510 return 0xFF;/* This SDO was not for us ! */
513 /* Test if the size of the SDO is ok */
514 if ( (*m).len != 8) {
515 MSG_ERR(0x1A67, "Error size SDO. CobId : ", (*m).cob_id.w);
516 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_GENERAL_ERROR);
520 if (whoami == SDO_CLIENT) {
521 MSG_WAR(0x3A68, "I am CLIENT. Received SDO from nodeId : ", nodeId);
524 MSG_WAR(0x3A69, "I am SERVER. Received SDO cobId : ", (*m).cob_id.w);
527 /* Testing the command specifier */
528 /* Allowed : cs = 0, 1, 2, 3, 4. (= all except those for block tranfert). */
529 /* cs = other : Not allowed -> abort. */
530 switch (getSDOcs(m->data[0])) {
534 if (whoami == SDO_SERVER) {
535 /* Receiving a download segment data. */
536 /* A SDO transfert should have been yet initiated. */
537 err = getSDOlineOnUse( d, nodeId, whoami, &line );
539 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
541 MSG_ERR(0x1A70, "SDO error : Received download segment for unstarted trans. index 0x1200 + ",
543 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
546 /* Reset the wathdog */
547 RestartSDO_TIMER(line)
548 MSG_WAR(0x3A71, "Received SDO download segment defined at index 0x1200 + ", nodeId);
549 index = d->transfers[line].index;
550 subIndex = d->transfers[line].subIndex;
552 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
553 MSG_ERR(0x1A72, "SDO error : Toggle error : ", getSDOt(m->data[0]));
554 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
557 /* Nb of data to be downloaded */
558 nbBytes = 7 - getSDOn3(m->data[0]);
559 /* Store the data in the transfert structure. */
560 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
562 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
565 /* Sending the SDO response, CS = 1 */
566 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender). */
567 sdo.body.data[0] = (1 << 5) | (d->transfers[line].toggle << 4);
568 for (i = 1 ; i < 8 ; i++)
569 sdo.body.data[i] = 0;
570 MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", nodeId);
571 sendSDO(d, whoami, sdo);
572 /* Inverting the toggle for the next segment. */
573 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
574 /* If it was the last segment, */
575 if (getSDOc(m->data[0])) {
576 /* Transfering line data to object dictionary. */
577 /* The code does not use the "d" of initiate frame. So it is safe if e=s=0 */
578 errorCode = SDOlineToObjdict(d, line);
580 MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0);
581 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
584 /* Release of the line */
585 resetSDOline(d, line);
586 MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", nodeId);
588 } /* end if SERVER */
589 else { /* if CLIENT */
591 /* It is a request for a previous upload segment. We should find a line opened for this.*/
592 err = getSDOlineOnUse( d, nodeId, whoami, &line);
594 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
596 MSG_ERR(0x1A75, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
597 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
600 /* Reset the wathdog */
601 RestartSDO_TIMER(line)
602 index = d->transfers[line].index;
603 subIndex = d->transfers[line].subIndex;
604 /* test of the toggle; */
605 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
606 MSG_ERR(0x1A76, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
607 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
610 /* nb of data to be uploaded */
611 nbBytes = 7 - getSDOn3(m->data[0]);
612 /* Storing the data in the line structure. */
613 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
615 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
618 /* Inverting the toggle for the next segment. */
619 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
620 /* If it was the last segment,*/
621 if ( getSDOc(m->data[0])) {
622 /* Put in state finished */
623 /* The code is safe for the case e=s=0 in initiate frame. */
625 d->transfers[line].state = SDO_FINISHED;
626 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
628 MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId);
630 else { /* more segments to receive */
631 /* Sending the request for the next segment. */
633 sdo.body.data[0] = (3 << 5) | (d->transfers[line].toggle << 4);
634 for (i = 1 ; i < 8 ; i++)
635 sdo.body.data[i] = 0;
636 sendSDO(d, whoami, sdo);
637 MSG_WAR(0x3A78, "SDO send upload segment request to nodeId", nodeId);
639 } /* End if CLIENT */
644 /* Receive of an initiate download */
645 if (whoami == SDO_SERVER) {
646 index = getSDOindex(m->data[1],m->data[2]);
647 subIndex = getSDOsubIndex(m->data[3]);
648 MSG_WAR(0x3A79, "Received SDO Initiate Download (to store data) defined at index 0x1200 + ",
650 MSG_WAR(0x3A80, "Writing at index : ", index);
651 MSG_WAR(0x3A80, "Writing at subIndex : ", subIndex);
653 /* Search if a SDO transfert have been yet initiated */
654 err = getSDOlineOnUse( d, nodeId, whoami, &line );
656 MSG_ERR(0x1A81, "SDO error : Transmission yet started.", 0);
657 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
660 /* No line on use. Great ! */
661 /* Try to open a new line. */
662 err = getSDOfreeLine( d, whoami, &line );
664 MSG_ERR(0x1A82, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
665 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
668 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
670 if (getSDOe(m->data[0])) { /* If SDO expedited */
671 /* nb of data to be downloaded */
672 nbBytes = 4 - getSDOn2(m->data[0]);
673 /* Storing the data in the line structure. */
674 d->transfers[line].count = nbBytes;
675 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
678 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
682 /* SDO expedited -> transfert finished. Data can be stored in the dictionary. */
683 /* The line will be reseted when it is downloading in the dictionary. */
684 MSG_WAR(0x3A83, "SDO Initiate Download is an expedited transfert. Finished.: ", nodeId);
685 /* Transfering line data to object dictionary. */
686 errorCode = SDOlineToObjdict(d, line);
688 MSG_ERR(0x1A84, "SDO error : Unable to copy the data in the object dictionary", 0);
689 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
692 /* Release of the line. */
693 resetSDOline(d, line);
695 else {/* So, if it is not an expedited transfert */
696 if (getSDOs(m->data[0])) {
697 /* TODO : if e and s = 0, not reading m->data[4] but put nbBytes = 0 */
698 nbBytes = m->data[4]; /* Transfert limited to 255 bytes. */
699 err = setSDOlineRestBytes(d, nodeId, nbBytes);
701 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
706 /*Sending a SDO, cs=3*/
707 sdo.nodeId = *d->bDeviceNodeId; /* The node id of the server, (here it is the sender).*/
708 sdo.body.data[0] = 3 << 5;
709 sdo.body.data[1] = index & 0xFF; /* LSB */
710 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
711 sdo.body.data[3] = subIndex;
712 for (i = 4 ; i < 8 ; i++)
713 sdo.body.data[i] = 0;
714 sendSDO(d, whoami, sdo);
715 } /* end if I am SERVER */
718 /* It is a response for a previous download segment. We should find a line opened for this. */
719 err = getSDOlineOnUse( d, nodeId, whoami, &line);
721 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
723 MSG_ERR(0x1A85, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
724 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
727 /* Reset the wathdog */
728 RestartSDO_TIMER(line)
729 index = d->transfers[line].index;
730 subIndex = d->transfers[line].subIndex;
731 /* test of the toggle; */
732 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
733 MSG_ERR(0x1A86, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
734 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
738 /* End transmission or downloading next segment. We need to know if it will be the last one. */
739 getSDOlineRestBytes(d, line, &nbBytes);
741 MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId);
743 d->transfers[line].state = SDO_FINISHED;
744 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
747 /* At least one transfer to send. */
749 /* several segments to download.*/
750 /* code to send the next segment. (cs = 0; c = 0) */
751 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
752 sdo.nodeId = nodeId; /* The server node Id; */
753 sdo.body.data[0] = (d->transfers[line].toggle << 4);
754 err = lineToSDO(d, line, 7, sdo.body.data + 1);
756 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
762 /* code to send the last segment. (cs = 0; c = 1)*/
763 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
764 sdo.nodeId = nodeId; /* The server node Id; */
765 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
766 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
768 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
771 for (i = nbBytes + 1 ; i < 8 ; i++)
772 sdo.body.data[i] = 0;
774 MSG_WAR(0x3A88, "SDO sending download segment to nodeId", nodeId);
775 sendSDO(d, whoami, sdo);
776 } /* end if I am a CLIENT */
781 /* Receive of an initiate upload.*/
782 if (whoami == SDO_SERVER) {
783 index = getSDOindex(m->data[1],m->data[2]);
784 subIndex = getSDOsubIndex(m->data[3]);
785 MSG_WAR(0x3A89, "Received SDO Initiate upload (to send data) defined at index 0x1200 + ",
787 MSG_WAR(0x3A90, "Reading at index : ", index);
788 MSG_WAR(0x3A91, "Reading at subIndex : ", subIndex);
789 /* Search if a SDO transfert have been yet initiated*/
790 err = getSDOlineOnUse( d, nodeId, whoami, &line );
792 MSG_ERR(0x1A92, "SDO error : Transmission yet started at line : ", line);
793 MSG_WAR(0x3A93, "nodeId = ", nodeId);
794 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
797 /* No line on use. Great !*/
798 /* Try to open a new line.*/
799 err = getSDOfreeLine( d, whoami, &line );
801 MSG_ERR(0x1A71, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
802 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
805 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
806 /* Transfer data from dictionary to the line structure. */
807 errorCode = objdictToSDOline(d, line);
810 MSG_ERR(0x1A94, "SDO error : Unable to copy the data from object dictionary. Err code : ",
812 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
815 /* Preparing the response.*/
816 getSDOlineRestBytes(d, line, &nbBytes); /* Nb bytes to transfer ? */
817 sdo.nodeId = nodeId; /* The server node Id; */
819 /* normal transfert. (segmented). */
820 /* code to send the initiate upload response. (cs = 2) */
821 sdo.body.data[0] = (2 << 5) | 1;
822 sdo.body.data[1] = index & 0xFF; /* LSB */
823 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
824 sdo.body.data[3] = subIndex;
825 sdo.body.data[4] = nbBytes; /* Limitation of canfestival2 : Max tranfert is 256 bytes.*/
826 /* It takes too much memory to upgrate to 2^32 because the size of data is also coded */
827 /* in the object dictionary, at every index and subindex. */
828 for (i = 5 ; i < 8 ; i++)
829 sdo.body.data[i] = 0;
830 MSG_WAR(0x3A95, "SDO. Sending normal upload initiate response defined at index 0x1200 + ", nodeId);
831 sendSDO(d, whoami, sdo);
834 /* Expedited upload. (cs = 2 ; e = 1) */
835 sdo.body.data[0] = (2 << 5) | ((4 - nbBytes) << 2) | 3;
836 sdo.body.data[1] = index & 0xFF; /* LSB */
837 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
838 sdo.body.data[3] = subIndex;
839 err = lineToSDO(d, line, nbBytes, sdo.body.data + 4);
841 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
844 for (i = 4 + nbBytes ; i < 8 ; i++)
845 sdo.body.data[i] = 0;
846 MSG_WAR(0x3A96, "SDO. Sending expedited upload initiate response defined at index 0x1200 + ",
848 sendSDO(d, whoami, sdo);
849 /* Release the line.*/
850 resetSDOline(d, line);
852 } /* end if I am SERVER*/
855 /* It is the response for the previous initiate upload request.*/
856 /* We should find a line opened for this. */
857 err = getSDOlineOnUse( d, nodeId, whoami, &line);
859 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
861 MSG_ERR(0x1A97, "SDO error : Received response for unknown upload request from nodeId", nodeId);
862 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
865 /* Reset the wathdog */
866 RestartSDO_TIMER(line)
867 index = d->transfers[line].index;
868 subIndex = d->transfers[line].subIndex;
870 if (getSDOe(m->data[0])) { /* If SDO expedited */
871 /* nb of data to be uploaded */
872 nbBytes = 4 - getSDOn2(m->data[0]);
873 /* Storing the data in the line structure. */
874 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
876 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
879 /* SDO expedited -> transfert finished. data are available via getReadResultNetworkDict(). */
880 MSG_WAR(0x3A98, "SDO expedited upload finished. Response received from node : ", nodeId);
882 d->transfers[line].count = nbBytes;
883 d->transfers[line].state = SDO_FINISHED;
884 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
887 else { /* So, if it is not an expedited transfert */
888 /* Storing the nb of data to receive. */
889 if (getSDOs(m->data[0])) {
890 nbBytes = m->data[4]; /* Remember the limitation to 255 bytes to transfert */
891 err = setSDOlineRestBytes(d, line, nbBytes);
893 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
897 /* Requesting next segment. (cs = 3) */
899 sdo.body.data[0] = 3 << 5;
900 for (i = 1 ; i < 8 ; i++)
901 sdo.body.data[i] = 0;
902 MSG_WAR(0x3A99, "SDO. Sending upload segment request to node : ", nodeId);
903 sendSDO(d, whoami, sdo);
905 } /* End if CLIENT */
910 if (whoami == SDO_SERVER) {
911 /* Receiving a upload segment. */
912 /* A SDO transfert should have been yet initiated. */
913 err = getSDOlineOnUse( d, nodeId, whoami, &line );
915 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
917 MSG_ERR(0x1AA0, "SDO error : Received upload segment for unstarted trans. index 0x1200 + ",
919 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
922 /* Reset the wathdog */
923 RestartSDO_TIMER(line)
924 MSG_WAR(0x3AA1, "Received SDO upload segment defined at index 0x1200 + ", nodeId);
925 index = d->transfers[line].index;
926 subIndex = d->transfers[line].subIndex;
928 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
929 MSG_ERR(0x1AA2, "SDO error : Toggle error : ", getSDOt(m->data[0]));
930 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
933 /* Uploading next segment. We need to know if it will be the last one. */
934 getSDOlineRestBytes(d, line, &nbBytes);
936 /* The segment to transfer is not the last one.*/
937 /* code to send the next segment. (cs = 0; c = 0) */
938 sdo.nodeId = nodeId; /* The server node Id; */
939 sdo.body.data[0] = (d->transfers[line].toggle << 4);
940 err = lineToSDO(d, line, 7, sdo.body.data + 1);
942 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
945 /* Inverting the toggle for the next tranfert. */
946 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
947 MSG_WAR(0x3AA3, "SDO. Sending upload segment defined at index 0x1200 + ", nodeId);
948 sendSDO(d, whoami, sdo);
952 /* code to send the last segment. (cs = 0; c = 1) */
953 sdo.nodeId = nodeId; /* The server node Id; */
954 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
955 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
957 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
960 for (i = nbBytes + 1 ; i < 8 ; i++)
961 sdo.body.data[i] = 0;
962 MSG_WAR(0x3AA4, "SDO. Sending last upload segment defined at index 0x1200 + ", nodeId);
963 sendSDO(d, whoami, sdo);
964 /* Release the line */
965 resetSDOline(d, line);
970 /* It is the response for the previous initiate download request. */
971 /* We should find a line opened for this. */
972 err = getSDOlineOnUse( d, nodeId, whoami, &line);
974 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
976 MSG_ERR(0x1AA5, "SDO error : Received response for unknown download request from nodeId", nodeId);
977 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
980 /* Reset the wathdog */
981 RestartSDO_TIMER(line)
982 index = d->transfers[line].index;
983 subIndex = d->transfers[line].subIndex;
984 /* End transmission or requesting next segment. */
985 getSDOlineRestBytes(d, line, &nbBytes);
987 MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId);
989 d->transfers[line].state = SDO_FINISHED;
990 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
994 /* more than one request to send */
995 /* code to send the next segment. (cs = 0; c = 0) */
996 sdo.nodeId = nodeId; /* The server node Id; */
997 sdo.body.data[0] = (d->transfers[line].toggle << 4);
998 err = lineToSDO(d, line, 7, sdo.body.data + 1);
1000 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1006 /* code to send the last segment. (cs = 0; c = 1) */
1007 sdo.nodeId = nodeId; /* The server node Id; */
1008 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
1009 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
1011 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
1014 for (i = nbBytes + 1 ; i < 8 ; i++)
1015 sdo.body.data[i] = 0;
1017 MSG_WAR(0x3AA7, "SDO sending download segment to nodeId", nodeId);
1018 sendSDO(d, whoami, sdo);
1020 } /* end if I am a CLIENT */
1024 abortCode = (*m).data[3] |
1025 ((UNS32)m->data[5] << 8) |
1026 ((UNS32)m->data[6] << 16) |
1027 ((UNS32)m->data[7] << 24);
1028 /* Received SDO abort. */
1029 /* Looking for the line concerned. */
1030 if (whoami == SDO_SERVER) {
1031 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1033 resetSDOline( d, line );
1034 MSG_WAR(0x3AA8, "SD0. Received SDO abort. Line released. Code : ", abortCode);
1037 MSG_WAR(0x3AA9, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1038 /* Tips : The end user has no way to know that the server node has received an abort SDO. */
1039 /* Its is ok, I think.*/
1041 else { /* If I am CLIENT */
1042 err = getSDOlineOnUse( d, nodeId, whoami, &line );
1044 /* The line *must* be released by the core program. */
1046 d->transfers[line].state = SDO_ABORTED_RCV;
1047 MSG_WAR(0x3AB0, "SD0. Received SDO abort. Line state ABORTED. Code : ", abortCode);
1050 MSG_WAR(0x3AB1, "SD0. Received SDO abort. No line found. Code : ", abortCode);
1054 /* Error : Unknown cs */
1055 MSG_ERR(0x1AB2, "SDO. Received unknown command specifier : ", getSDOcs(m->data[0]));
1062 /*******************************************************************)******/
1063 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1064 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback)
1069 s_SDO sdo; /* SDO to transmit */
1073 UNS32 *pNodeIdServer;
1076 MSG_WAR(0x3AC0, "Send SDO to write in the dictionary of node : ", nodeId);
1077 MSG_WAR(0x3AC1, " At index : ", index);
1078 MSG_WAR(0x3AC2, " subIndex : ", subIndex);
1079 MSG_WAR(0x3AC3, " nb bytes : ", count);
1081 /* Verify that there is no SDO communication yet. */
1082 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1084 MSG_ERR(0x1AC4, "SDO error : Communication yet established. with node : ", nodeId);
1087 /* Taking the line ... */
1088 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1090 MSG_ERR(0x1AC5, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1093 /* Check which SDO to use to communicate with the node */
1094 offset = d->firstIndex->SDO_CLT;
1095 lastIndex = d->lastIndex->SDO_CLT;
1097 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
1101 while (offset <= lastIndex) {
1102 if (d->objdict[offset].bSubCount <= 3) {
1103 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
1106 /* looking for the nodeId server */
1107 pNodeIdServer = d->objdict[offset].pSubindex[3].pObject;
1108 nodeIdServer = *pNodeIdServer;
1109 MSG_WAR(0x1AD2, "index : ", 0x1280 + i);
1110 MSG_WAR(0x1AD3, "nodeIdServer : ", nodeIdServer);
1112 if(nodeIdServer == (UNS32)nodeId) {
1120 MSG_ERR(0x1AC9, "SDO. Error. No client found to communicate with node : ", nodeId);
1123 MSG_WAR(0x3AD0," SDO client defined at index : ", 0x1280 + i);
1124 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
1125 d->transfers[line].count = count;
1126 d->transfers[line].dataType = dataType;
1128 /* Copy data to transfers structure. */
1129 for (j = 0 ; j < count ; j++) {
1130 # ifdef CANOPEN_BIG_ENDIAN
1132 d->transfers[line].data[count - 1 - j] = ((char *)data)[j];
1133 else /* String of bytes. */
1134 d->transfers[line].data[j] = ((char *)data)[j];
1136 d->transfers[line].data[j] = ((char *)data)[j];
1139 /* Send the SDO to the server. Initiate download, cs=1. */
1140 sdo.nodeId = nodeId;
1141 if (count <= 4) { /* Expedited transfert */
1142 sdo.body.data[0] = (1 << 5) | ((4 - count) << 2) | 3;
1143 for (i = 4 ; i < 8 ; i++)
1144 sdo.body.data[i] = d->transfers[line].data[i - 4];
1145 d->transfers[line].offset = count;
1147 else { /* Normal transfert */
1148 sdo.body.data[0] = (1 << 5) | 1;
1149 sdo.body.data[4] = count; /* nb of byte to transmit. Max = 255. (canfestival2 limitation). */
1150 for (i = 5 ; i < 8 ; i++)
1151 sdo.body.data[i] = 0;
1153 sdo.body.data[1] = index & 0xFF; /* LSB */
1154 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1155 sdo.body.data[3] = subIndex;
1157 err = sendSDO(d, SDO_CLIENT, sdo);
1159 MSG_ERR(0x1AD1, "SDO. Error while sending SDO to node : ", nodeId);
1160 /* release the line */
1161 resetSDOline(d, line);
1164 d->transfers[line].Callback = Callback;
1168 /*--------------------------------------------------------------------------*/
1170 UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
1171 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data)
1173 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, NULL);
1176 /*--------------------------------------------------------------------------*/
1178 UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index,
1179 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback)
1181 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback);
1185 /***************************************************************************/
1186 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1192 s_SDO sdo; /* SDO to transmit */
1193 UNS32 *pNodeIdServer;
1197 MSG_WAR(0x3AD5, "Send SDO to read in the dictionary of node : ", nodeId);
1198 MSG_WAR(0x3AD6, " At index : ", index);
1199 MSG_WAR(0x3AD7, " subIndex : ", subIndex);
1202 /* Verify that there is no SDO communication yet. */
1203 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1205 MSG_ERR(0x1AD8, "SDO error : Communication yet established. with node : ", nodeId);
1208 /* Taking the line ... */
1209 err = getSDOfreeLine( d, SDO_CLIENT, &line );
1211 MSG_ERR(0x1AD9, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
1215 MSG_WAR(0x3AE0, "Transmission on line : ", line);
1217 /* Check which SDO to use to communicate with the node */
1218 offset = d->firstIndex->SDO_CLT;
1219 lastIndex = d->lastIndex->SDO_CLT;
1221 MSG_ERR(0x1AE1, "writeNetworkDict : No SDO client index found", 0);
1225 while (offset <= lastIndex) {
1226 if (d->objdict[offset].bSubCount <= 3) {
1227 MSG_ERR(0x1AE2, "Subindex 3 not found at index ", 0x1280 + i);
1230 /* looking for the nodeId server */
1231 pNodeIdServer = d->objdict[offset].pSubindex[3].pObject;
1232 nodeIdServer = *pNodeIdServer;
1234 if(nodeIdServer == (UNS32)nodeId) {
1242 MSG_ERR(0x1AE3, "SDO. Error. No client found to communicate with node : ", nodeId);
1245 MSG_WAR(0x3AE4," SDO client defined at index : ", 0x1280 + i);
1246 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
1247 getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1248 sdo.nodeId = nodeId;
1249 /* Send the SDO to the server. Initiate upload, cs=2. */
1250 d->transfers[line].dataType = dataType;
1251 sdo.body.data[0] = (2 << 5);
1252 sdo.body.data[1] = index & 0xFF; /* LSB */
1253 sdo.body.data[2] = (index >> 8) & 0xFF; /* MSB */
1254 sdo.body.data[3] = subIndex;
1255 for (i = 4 ; i < 8 ; i++)
1256 sdo.body.data[i] = 0;
1257 err = sendSDO(d, SDO_CLIENT, sdo);
1259 MSG_ERR(0x1AE5, "SDO. Error while sending SDO to node : ", nodeId);
1260 /* release the line */
1261 resetSDOline(d, line);
1264 d->transfers[line].Callback = Callback;
1268 /*--------------------------------------------------------------------------*/
1270 UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType)
1272 return _readNetworkDict (d, nodeId, index, subIndex, dataType, NULL);
1275 /*--------------------------------------------------------------------------*/
1276 UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
1278 return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
1281 /***************************************************************************/
1283 UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size,
1291 /* Looking for the line tranfert. */
1292 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1294 MSG_ERR(0x1AF0, "SDO error : No line found for communication with node : ", nodeId);
1295 return SDO_ABORTED_INTERNAL;
1297 if (d->transfers[line].state != SDO_FINISHED)
1298 return d->transfers[line].state;
1300 /* Transfert is finished. Put the value in the data. */
1301 * size = d->transfers[line].count;
1302 for ( i = 0 ; i < *size ; i++) {
1303 # ifdef CANOPEN_BIG_ENDIAN
1304 if (d->transfers[line].dataType != visible_string)
1305 ( (char *) data)[*size - 1 - i] = d->transfers[line].data[i];
1306 else /* String of bytes. */
1307 ( (char *) data)[i] = d->transfers[line].data[i];
1309 ( (char *) data)[i] = d->transfers[line].data[i];
1312 return SDO_FINISHED;
1315 /***************************************************************************/
1317 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode)
1323 /* Looking for the line tranfert. */
1324 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
1326 MSG_ERR(0x1AF1, "SDO error : No line found for communication with node : ", nodeId);
1327 return SDO_ABORTED_INTERNAL;
1329 * abortCode = d->transfers[line].abortCode;
1330 return d->transfers[line].state;