00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "objacces.h"
00027 #include "sdo.h"
00028 #include "canfestival.h"
00029
00030
00031 #define NO_INLINE
00032
00033 #ifdef NO_INLINE
00034 #define INLINE
00035 #else
00036 #define INLINE inline
00037 #endif
00038
00039
00040
00042 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
00043 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize);
00044
00046 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex,
00047 UNS8 dataType, SDOCallback_t Callback);
00048
00049
00050
00051
00052
00055 #define getSDOcs(byte) (byte >> 5)
00056
00059 #define getSDOn2(byte) ((byte >> 2) & 3)
00060
00063 #define getSDOn3(byte) ((byte >> 1) & 7)
00064
00067 #define getSDOe(byte) ((byte >> 1) & 1)
00068
00071 #define getSDOs(byte) (byte & 1)
00072
00075 #define getSDOc(byte) (byte & 1)
00076
00079 #define getSDOt(byte) ((byte >> 4) & 1)
00080
00083 #define getSDOindex(byte1, byte2) ((byte2 << 8) | (byte1))
00084
00088 #define getSDOsubIndex(byte3) (byte3)
00089
00090
00091
00092
00093 void SDOTimeoutAlarm(CO_Data* d, UNS32 id)
00094 {
00095 MSG_ERR(0x1A01, "SDO timeout. SDO response not received.", 0);
00096 MSG_WAR(0x2A02, "server node : ", d->transfers[id].nodeId);
00097 MSG_WAR(0x2A02, " index : ", d->transfers[id].index);
00098 MSG_WAR(0x2A02, " subIndex : ", d->transfers[id].subIndex);
00099
00100 d->transfers[id].timer = TIMER_NONE;
00101
00102 d->transfers[id].state = SDO_ABORTED_INTERNAL;
00103
00104 sendSDOabort(d, d->transfers[id].whoami,
00105 d->transfers[id].index, d->transfers[id].subIndex, SDOABT_TIMED_OUT);
00106 d->transfers[id].abortCode = SDOABT_TIMED_OUT;
00107
00108 if(d->transfers[id].Callback)
00109
00110 (*d->transfers[id].Callback)(d,d->transfers[id].nodeId);
00111 else if(d->transfers[id].whoami == SDO_SERVER)
00112
00113 resetSDOline(d, (UNS8)id);
00114 }
00115
00116 #define StopSDO_TIMER(id) \
00117 MSG_WAR(0x3A05, "StopSDO_TIMER for line : ", line);\
00118 d->transfers[id].timer = DelAlarm(d->transfers[id].timer);
00119
00120 #define StartSDO_TIMER(id) \
00121 MSG_WAR(0x3A06, "StartSDO_TIMER for line : ", line);\
00122 d->transfers[id].timer = SetAlarm(d,id,&SDOTimeoutAlarm,MS_TO_TIMEVAL(SDO_TIMEOUT_MS),0);
00123
00124 #define RestartSDO_TIMER(id) \
00125 MSG_WAR(0x3A07, "restartSDO_TIMER for line : ", line);\
00126 if(d->transfers[id].timer != TIMER_NONE) { StopSDO_TIMER(id) StartSDO_TIMER(id) }
00127
00128
00131 void resetSDO (CO_Data* d)
00132 {
00133 UNS8 j;
00134
00135
00136 for (j = 0 ; j < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; j++)
00137 resetSDOline(d, j);
00138 }
00139
00140
00141 UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line)
00142 {
00143 UNS8 size;
00144 UNS32 errorCode;
00145 MSG_WAR(0x3A08, "Enter in SDOlineToObjdict ", line);
00146 size = (UNS8)d->transfers[line].count;
00147 errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
00148 (void *) d->transfers[line].data, &size, 1);
00149 if (errorCode != OD_SUCCESSFUL)
00150 return errorCode;
00151 MSG_WAR(0x3A08, "exit of SDOlineToObjdict ", line);
00152 return 0;
00153
00154 }
00155
00156
00157 UNS32 objdictToSDOline (CO_Data* d, UNS8 line)
00158 {
00159 UNS8 size = 0;
00160 UNS8 dataType;
00161 UNS32 errorCode;
00162
00163 MSG_WAR(0x3A05, "objdict->line index : ", d->transfers[line].index);
00164 MSG_WAR(0x3A06, " subIndex : ", d->transfers[line].subIndex);
00165
00166 errorCode = getODentry(d, d->transfers[line].index,
00167 d->transfers[line].subIndex,
00168 (void *)d->transfers[line].data,
00169 &size, &dataType, 0);
00170
00171 if (errorCode != OD_SUCCESSFUL)
00172 return errorCode;
00173
00174 d->transfers[line].count = size;
00175 d->transfers[line].offset = 0;
00176 #if 0
00177
00178 {
00179 UNS8 i;
00180 for (i = 0 ; i < 10 ; i++) {
00181 MSG_WAR(i, "data= ", d->transfers[line].data[i]);
00182 }
00183 }
00184 #endif
00185 return 0;
00186 }
00187
00188
00189 UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data) {
00190 UNS8 i;
00191 UNS8 offset;
00192
00193 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
00194 MSG_ERR(0x1A10,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
00195 return 0xFF;
00196 }
00197 if ((d->transfers[line].offset + nbBytes) > d->transfers[line].count) {
00198 MSG_ERR(0x1A11,"SDO Size of data too large. Exceed count", nbBytes);
00199 return 0xFF;
00200 }
00201 offset = (UNS8)d->transfers[line].offset;
00202 for (i = 0 ; i < nbBytes ; i++)
00203 * (data + i) = d->transfers[line].data[offset + i];
00204 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
00205 return 0;
00206 }
00207
00208
00209
00210 UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data)
00211 {
00212 UNS8 i;
00213 UNS8 offset;
00214
00215 if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) {
00216 MSG_ERR(0x1A15,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
00217 return 0xFF;
00218 }
00219 offset = (UNS8)d->transfers[line].offset;
00220 for (i = 0 ; i < nbBytes ; i++)
00221 d->transfers[line].data[offset + i] = * (data + i);
00222 d->transfers[line].offset = d->transfers[line].offset + nbBytes;
00223 return 0;
00224 }
00225
00226
00227 UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index,
00228 UNS8 subIndex, UNS32 abortCode)
00229 {
00230 UNS8 err;
00231 UNS8 line;
00232 err = getSDOlineOnUse( d, nodeId, whoami, &line );
00233 if (!err)
00234 MSG_WAR(0x3A20, "FailedSDO : line found : ", line);
00235 if ((! err) && (whoami == SDO_SERVER)) {
00236 resetSDOline( d, line );
00237 MSG_WAR(0x3A21, "FailedSDO : line released : ", line);
00238 }
00239 if ((! err) && (whoami == SDO_CLIENT)) {
00240 StopSDO_TIMER(line);
00241 d->transfers[line].state = SDO_ABORTED_INTERNAL;
00242 }
00243 MSG_WAR(0x3A22, "Sending SDO abort ", 0);
00244 err = sendSDOabort(d, whoami, index, subIndex, abortCode);
00245 if (err) {
00246 MSG_WAR(0x3A23, "Unable to send the SDO abort", 0);
00247 return 0xFF;
00248 }
00249 return 0;
00250 }
00251
00252
00253 void resetSDOline ( CO_Data* d, UNS8 line )
00254 {
00255 UNS8 i;
00256 MSG_WAR(0x3A25, "reset SDO line nb : ", line);
00257 initSDOline(d, line, 0, 0, 0, SDO_RESET);
00258 for (i = 0 ; i < SDO_MAX_LENGTH_TRANSFERT ; i++)
00259 d->transfers[line].data[i] = 0;
00260 }
00261
00262
00263 UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state)
00264 {
00265 MSG_WAR(0x3A25, "init SDO line nb : ", line);
00266 if (state == SDO_DOWNLOAD_IN_PROGRESS || state == SDO_UPLOAD_IN_PROGRESS){
00267 StartSDO_TIMER(line)
00268 }else{
00269 StopSDO_TIMER(line)
00270 }
00271 d->transfers[line].nodeId = nodeId;
00272 d->transfers[line].index = index;
00273 d->transfers[line].subIndex = subIndex;
00274 d->transfers[line].state = state;
00275 d->transfers[line].toggle = 0;
00276 d->transfers[line].count = 0;
00277 d->transfers[line].offset = 0;
00278 d->transfers[line].dataType = 0;
00279 d->transfers[line].Callback = NULL;
00280 return 0;
00281 }
00282
00283
00284 UNS8 getSDOfreeLine ( CO_Data* d, UNS8 whoami, UNS8 *line )
00285 {
00286
00287 UNS8 i;
00288
00289 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
00290 if ( d->transfers[i].state == SDO_RESET ) {
00291 *line = i;
00292 d->transfers[i].whoami = whoami;
00293 return 0;
00294 }
00295 }
00296 MSG_ERR(0x1A25, "Too many SDO in progress. Aborted.", i);
00297 return 0xFF;
00298 }
00299
00300
00301 UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line)
00302 {
00303
00304 UNS8 i;
00305
00306 for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){
00307 if ( (d->transfers[i].state != SDO_RESET) &&
00308 (d->transfers[i].nodeId == nodeId) &&
00309 (d->transfers[i].whoami == whoami) ) {
00310 *line = i;
00311 return 0;
00312 }
00313 }
00314 return 0xFF;
00315 }
00316
00317
00318 UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami)
00319 {
00320 UNS8 err;
00321 UNS8 line;
00322 err = getSDOlineOnUse(d, nodeId, whoami, &line);
00323 if (err) {
00324 MSG_WAR(0x2A30, "No SDO communication to close for node : ", nodeId);
00325 return 0xFF;
00326 }
00327 resetSDOline(d, line);
00328 return 0;
00329 }
00330
00331
00332 UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 * nbBytes)
00333 {
00334 if (d->transfers[line].count == 0)
00335 * nbBytes = 0;
00336 else
00337 * nbBytes = (UNS8)d->transfers[line].count - (UNS8)d->transfers[line].offset;
00338 return 0;
00339 }
00340
00341
00342 UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 nbBytes)
00343 {
00344 if (nbBytes > SDO_MAX_LENGTH_TRANSFERT) {
00345 MSG_ERR(0x1A35,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
00346 return 0xFF;
00347 }
00348 d->transfers[line].count = nbBytes;
00349 return 0;
00350 }
00351
00352
00353
00354 UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo)
00355 {
00356 UNS16 offset;
00357 UNS16 lastIndex;
00358 UNS8 found = 0;
00359 Message m;
00360 UNS8 i;
00361 UNS32 * pwCobId = NULL;
00362 UNS32 * pwNodeId = NULL;
00363
00364 MSG_WAR(0x3A38, "sendSDO",0);
00365 if( !((d->nodeState == Operational) || (d->nodeState == Pre_operational ))) {
00366 MSG_WAR(0x2A39, "unable to send the SDO (not in op or pre-op mode", d->nodeState);
00367 return 0xFF;
00368 }
00369
00370
00371 if ( whoami == SDO_SERVER ) {
00372 offset = d->firstIndex->SDO_SVR;
00373 if (offset == 0) {
00374 MSG_ERR(0x1A42, "SendSDO : No SDO server found", 0);
00375 return 0xFF;
00376 }
00377 pwCobId = d->objdict[offset].pSubindex[2].pObject;
00378 MSG_WAR(0x3A41, "I am server. cobId : ", *pwCobId);
00379 }
00380 else {
00381
00382 UNS16 sdoNum = 0;
00383 offset = d->firstIndex->SDO_CLT;
00384 lastIndex = d->lastIndex->SDO_CLT;
00385 if (offset == 0) {
00386 MSG_ERR(0x1A42, "SendSDO : No SDO client index found", 0);
00387 return 0xFF;
00388 }
00389
00390 while (offset <= lastIndex){
00391 MSG_WAR(0x3A43,"Reading index : ", 0x1280 + sdoNum);
00392 if (d->objdict[offset].bSubCount <= 3) {
00393 MSG_ERR(0x1A28, "Subindex 3 not found at index ", 0x1280 + sdoNum);
00394 return 0xFF;
00395 }
00396 pwNodeId = d->objdict[offset].pSubindex[3].pObject;
00397 MSG_WAR(0x3A44, "Found nodeId server = ", *pwNodeId);
00398 if(*pwNodeId == sdo.nodeId) {
00399 found = 1;
00400 break;
00401 }
00402 offset ++;
00403 sdoNum ++;
00404 }
00405 if (! found){
00406 MSG_WAR (0x2A45, "No SDO client corresponds to the mesage to send to node ", sdo.nodeId);
00407 return 0xFF;
00408 }
00409
00410 pwCobId = d->objdict[offset].pSubindex[1].pObject;
00411 }
00412
00413 m.cob_id.w = *pwCobId;
00414 m.rtr = NOT_A_REQUEST;
00415
00416 m.len = 8;
00417 for (i = 0 ; i < 8 ; i++) {
00418 m.data[i] = sdo.body.data[i];
00419 }
00420 return canSend(d->canHandle,&m);
00421 }
00422
00423
00424 UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS16 index, UNS8 subIndex, UNS32 abortCode)
00425 {
00426 s_SDO sdo;
00427 UNS8 ret;
00428 MSG_WAR(0x2A50,"Sending SDO abort ", abortCode);
00429 sdo.nodeId = *d->bDeviceNodeId;
00430 sdo.body.data[0] = 0x80;
00431
00432 sdo.body.data[1] = index & 0xFF;
00433 sdo.body.data[2] = (index >> 8) & 0xFF;
00434
00435 sdo.body.data[3] = subIndex;
00436
00437 sdo.body.data[4] = (UNS8)(abortCode & 0xFF);
00438 sdo.body.data[5] = (UNS8)((abortCode >> 8) & 0xFF);
00439 sdo.body.data[6] = (UNS8)((abortCode >> 16) & 0xFF);
00440 sdo.body.data[7] = (UNS8)((abortCode >> 24) & 0xFF);
00441 ret = sendSDO(d, whoami, sdo);
00442
00443 return ret;
00444 }
00445
00446
00447 UNS8 proceedSDO (CO_Data* d, Message *m)
00448 {
00449 UNS8 err;
00450 UNS8 line;
00451 UNS8 nbBytes;
00452 UNS8 nodeId = 0;
00453 UNS32 nodeId_32;
00454 UNS32 *pNodeId = NULL;
00455 UNS8 whoami = SDO_UNKNOWN;
00456 UNS32 errorCode;
00457 s_SDO sdo;
00458 UNS16 index;
00459 UNS8 subIndex;
00460 UNS32 abortCode;
00461 UNS8 i,j;
00462 UNS32 * pCobId = NULL;
00463 UNS16 offset;
00464 UNS16 lastIndex;
00465
00466 MSG_WAR(0x3A60, "proceedSDO ", 0);
00467 whoami = SDO_UNKNOWN;
00468
00469
00470 offset = d->firstIndex->SDO_SVR;
00471 lastIndex = d->lastIndex->SDO_SVR;
00472 j = 0;
00473 if(offset) while (offset <= lastIndex) {
00474 if (d->objdict[offset].bSubCount <= 1) {
00475 MSG_ERR(0x1A61, "Subindex 1 not found at index ", 0x1200 + j);
00476 return 0xFF;
00477 }
00478 pCobId = d->objdict[offset].pSubindex[1].pObject;
00479 if ( *pCobId == (*m).cob_id.w ) {
00480 whoami = SDO_SERVER;
00481 MSG_WAR(0x3A62, "proceedSDO. I am server. index : ", 0x1200 + j);
00482
00483
00484 nodeId = j;
00485 break;
00486 }
00487 j++;
00488 offset++;
00489 }
00490 if (whoami == SDO_UNKNOWN) {
00491
00492 offset = d->firstIndex->SDO_CLT;
00493 lastIndex = d->lastIndex->SDO_CLT;
00494 j = 0;
00495 if(offset) while (offset <= lastIndex) {
00496 if (d->objdict[offset].bSubCount <= 3) {
00497 MSG_ERR(0x1A63, "Subindex 3 not found at index ", 0x1280 + j);
00498 return 0xFF;
00499 }
00500
00501 pCobId = d->objdict[offset].pSubindex[2].pObject;
00502 if (*pCobId == (*m).cob_id.w ) {
00503
00504 pNodeId = d->objdict[offset].pSubindex[3].pObject;
00505 whoami = SDO_CLIENT;
00506 nodeId_32 = *pNodeId;
00507 nodeId = (UNS8)nodeId_32;
00508 MSG_WAR(0x3A64, "proceedSDO. I am server. index : ", 0x1280 + j);
00509 MSG_WAR(0x3A65, " Server nodeId : ", nodeId);
00510 break;
00511 }
00512 j++;
00513 offset++;
00514 }
00515 }
00516 if (whoami == SDO_UNKNOWN) {
00517 return 0xFF;
00518 }
00519
00520
00521 if ( (*m).len != 8) {
00522 MSG_ERR(0x1A67, "Error size SDO. CobId : ", (*m).cob_id.w);
00523 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_GENERAL_ERROR);
00524 return 0xFF;
00525 }
00526
00527 if (whoami == SDO_CLIENT) {
00528 MSG_WAR(0x3A68, "I am CLIENT. Received SDO from nodeId : ", nodeId);
00529 }
00530 else {
00531 MSG_WAR(0x3A69, "I am SERVER. Received SDO cobId : ", (*m).cob_id.w);
00532 }
00533
00534
00535
00536
00537 switch (getSDOcs(m->data[0])) {
00538
00539 case 0:
00540
00541 if (whoami == SDO_SERVER) {
00542
00543
00544 err = getSDOlineOnUse( d, nodeId, whoami, &line );
00545 if (!err)
00546 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
00547 if (err) {
00548 MSG_ERR(0x1A70, "SDO error : Received download segment for unstarted trans. index 0x1200 + ",
00549 nodeId);
00550 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
00551 return 0xFF;
00552 }
00553
00554 RestartSDO_TIMER(line)
00555 MSG_WAR(0x3A71, "Received SDO download segment defined at index 0x1200 + ", nodeId);
00556 index = d->transfers[line].index;
00557 subIndex = d->transfers[line].subIndex;
00558
00559 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
00560 MSG_ERR(0x1A72, "SDO error : Toggle error : ", getSDOt(m->data[0]));
00561 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
00562 return 0xFF;
00563 }
00564
00565 nbBytes = 7 - getSDOn3(m->data[0]);
00566
00567 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
00568 if (err) {
00569 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00570 return 0xFF;
00571 }
00572
00573 sdo.nodeId = *d->bDeviceNodeId;
00574 sdo.body.data[0] = (1 << 5) | (d->transfers[line].toggle << 4);
00575 for (i = 1 ; i < 8 ; i++)
00576 sdo.body.data[i] = 0;
00577 MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", nodeId);
00578 sendSDO(d, whoami, sdo);
00579
00580 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
00581
00582 if (getSDOc(m->data[0])) {
00583
00584
00585 errorCode = SDOlineToObjdict(d, line);
00586 if (errorCode) {
00587 MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0);
00588 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
00589 return 0xFF;
00590 }
00591
00592 resetSDOline(d, line);
00593 MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", nodeId);
00594 }
00595 }
00596 else {
00597
00598
00599 err = getSDOlineOnUse( d, nodeId, whoami, &line);
00600 if (!err)
00601 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
00602 if (err) {
00603 MSG_ERR(0x1A75, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
00604 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
00605 return 0xFF;
00606 }
00607
00608 RestartSDO_TIMER(line)
00609 index = d->transfers[line].index;
00610 subIndex = d->transfers[line].subIndex;
00611
00612 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
00613 MSG_ERR(0x1A76, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
00614 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
00615 return 0xFF;
00616 }
00617
00618 nbBytes = 7 - getSDOn3(m->data[0]);
00619
00620 err = SDOtoLine(d, line, nbBytes, (*m).data + 1);
00621 if (err) {
00622 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00623 return 0xFF;
00624 }
00625
00626 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
00627
00628 if ( getSDOc(m->data[0])) {
00629
00630
00631 StopSDO_TIMER(line)
00632 d->transfers[line].state = SDO_FINISHED;
00633 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
00634
00635 MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId);
00636 }
00637 else {
00638
00639 sdo.nodeId = nodeId;
00640 sdo.body.data[0] = (3 << 5) | (d->transfers[line].toggle << 4);
00641 for (i = 1 ; i < 8 ; i++)
00642 sdo.body.data[i] = 0;
00643 sendSDO(d, whoami, sdo);
00644 MSG_WAR(0x3A78, "SDO send upload segment request to nodeId", nodeId);
00645 }
00646 }
00647 break;
00648
00649 case 1:
00650
00651
00652 if (whoami == SDO_SERVER) {
00653 index = getSDOindex(m->data[1],m->data[2]);
00654 subIndex = getSDOsubIndex(m->data[3]);
00655 MSG_WAR(0x3A79, "Received SDO Initiate Download (to store data) defined at index 0x1200 + ",
00656 nodeId);
00657 MSG_WAR(0x3A80, "Writing at index : ", index);
00658 MSG_WAR(0x3A80, "Writing at subIndex : ", subIndex);
00659
00660
00661 err = getSDOlineOnUse( d, nodeId, whoami, &line );
00662 if (! err) {
00663 MSG_ERR(0x1A81, "SDO error : Transmission yet started.", 0);
00664 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
00665 return 0xFF;
00666 }
00667
00668
00669 err = getSDOfreeLine( d, whoami, &line );
00670 if (err) {
00671 MSG_ERR(0x1A82, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
00672 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
00673 return 0xFF;
00674 }
00675 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
00676
00677 if (getSDOe(m->data[0])) {
00678
00679 nbBytes = 4 - getSDOn2(m->data[0]);
00680
00681 d->transfers[line].count = nbBytes;
00682 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
00683
00684 if (err) {
00685 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00686 return 0xFF;
00687 }
00688
00689
00690
00691 MSG_WAR(0x3A83, "SDO Initiate Download is an expedited transfert. Finished.: ", nodeId);
00692
00693 errorCode = SDOlineToObjdict(d, line);
00694 if (errorCode) {
00695 MSG_ERR(0x1A84, "SDO error : Unable to copy the data in the object dictionary", 0);
00696 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
00697 return 0xFF;
00698 }
00699
00700 resetSDOline(d, line);
00701 }
00702 else {
00703 if (getSDOs(m->data[0])) {
00704
00705 nbBytes = m->data[4];
00706 err = setSDOlineRestBytes(d, nodeId, nbBytes);
00707 if (err) {
00708 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00709 return 0xFF;
00710 }
00711 }
00712 }
00713
00714 sdo.nodeId = *d->bDeviceNodeId;
00715 sdo.body.data[0] = 3 << 5;
00716 sdo.body.data[1] = index & 0xFF;
00717 sdo.body.data[2] = (index >> 8) & 0xFF;
00718 sdo.body.data[3] = subIndex;
00719 for (i = 4 ; i < 8 ; i++)
00720 sdo.body.data[i] = 0;
00721 sendSDO(d, whoami, sdo);
00722 }
00723 else {
00724
00725
00726 err = getSDOlineOnUse( d, nodeId, whoami, &line);
00727 if (!err)
00728 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
00729 if (err) {
00730 MSG_ERR(0x1A85, "SDO error : Received segment response for unknown trans. from nodeId", nodeId);
00731 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
00732 return 0xFF;
00733 }
00734
00735 RestartSDO_TIMER(line)
00736 index = d->transfers[line].index;
00737 subIndex = d->transfers[line].subIndex;
00738
00739 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
00740 MSG_ERR(0x1A86, "SDO error : Received segment response Toggle error. from nodeId", nodeId);
00741 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
00742 return 0xFF;
00743 }
00744
00745
00746 getSDOlineRestBytes(d, line, &nbBytes);
00747 if (nbBytes == 0) {
00748 MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId);
00749 StopSDO_TIMER(line)
00750 d->transfers[line].state = SDO_FINISHED;
00751 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
00752 return 0x00;
00753 }
00754
00755 if (nbBytes > 7) {
00756
00757
00758 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
00759 sdo.nodeId = nodeId;
00760 sdo.body.data[0] = (d->transfers[line].toggle << 4);
00761 err = lineToSDO(d, line, 7, sdo.body.data + 1);
00762 if (err) {
00763 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00764 return 0xFF;
00765 }
00766 }
00767 else {
00768
00769
00770 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
00771 sdo.nodeId = nodeId;
00772 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
00773 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
00774 if (err) {
00775 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00776 return 0xFF;
00777 }
00778 for (i = nbBytes + 1 ; i < 8 ; i++)
00779 sdo.body.data[i] = 0;
00780 }
00781 MSG_WAR(0x3A88, "SDO sending download segment to nodeId", nodeId);
00782 sendSDO(d, whoami, sdo);
00783 }
00784 break;
00785
00786 case 2:
00787
00788
00789 if (whoami == SDO_SERVER) {
00790 index = getSDOindex(m->data[1],m->data[2]);
00791 subIndex = getSDOsubIndex(m->data[3]);
00792 MSG_WAR(0x3A89, "Received SDO Initiate upload (to send data) defined at index 0x1200 + ",
00793 nodeId);
00794 MSG_WAR(0x3A90, "Reading at index : ", index);
00795 MSG_WAR(0x3A91, "Reading at subIndex : ", subIndex);
00796
00797 err = getSDOlineOnUse( d, nodeId, whoami, &line );
00798 if (! err) {
00799 MSG_ERR(0x1A92, "SDO error : Transmission yet started at line : ", line);
00800 MSG_WAR(0x3A93, "nodeId = ", nodeId);
00801 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
00802 return 0xFF;
00803 }
00804
00805
00806 err = getSDOfreeLine( d, whoami, &line );
00807 if (err) {
00808 MSG_ERR(0x1A71, "SDO error : No line free, too many SDO in progress. Aborted.", 0);
00809 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR);
00810 return 0xFF;
00811 }
00812 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
00813
00814 errorCode = objdictToSDOline(d, line);
00815
00816 if (errorCode) {
00817 MSG_ERR(0x1A94, "SDO error : Unable to copy the data from object dictionary. Err code : ",
00818 errorCode);
00819 failedSDO(d, nodeId, whoami, index, subIndex, errorCode);
00820 return 0xFF;
00821 }
00822
00823 getSDOlineRestBytes(d, line, &nbBytes);
00824 sdo.nodeId = nodeId;
00825 if (nbBytes > 4) {
00826
00827
00828 sdo.body.data[0] = (2 << 5) | 1;
00829 sdo.body.data[1] = index & 0xFF;
00830 sdo.body.data[2] = (index >> 8) & 0xFF;
00831 sdo.body.data[3] = subIndex;
00832 sdo.body.data[4] = nbBytes;
00833
00834
00835 for (i = 5 ; i < 8 ; i++)
00836 sdo.body.data[i] = 0;
00837 MSG_WAR(0x3A95, "SDO. Sending normal upload initiate response defined at index 0x1200 + ", nodeId);
00838 sendSDO(d, whoami, sdo);
00839 }
00840 else {
00841
00842 sdo.body.data[0] = (2 << 5) | ((4 - nbBytes) << 2) | 3;
00843 sdo.body.data[1] = index & 0xFF;
00844 sdo.body.data[2] = (index >> 8) & 0xFF;
00845 sdo.body.data[3] = subIndex;
00846 err = lineToSDO(d, line, nbBytes, sdo.body.data + 4);
00847 if (err) {
00848 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00849 return 0xFF;
00850 }
00851 for (i = 4 + nbBytes ; i < 8 ; i++)
00852 sdo.body.data[i] = 0;
00853 MSG_WAR(0x3A96, "SDO. Sending expedited upload initiate response defined at index 0x1200 + ",
00854 nodeId);
00855 sendSDO(d, whoami, sdo);
00856
00857 resetSDOline(d, line);
00858 }
00859 }
00860 else {
00861
00862
00863
00864 err = getSDOlineOnUse( d, nodeId, whoami, &line);
00865 if (!err)
00866 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
00867 if (err) {
00868 MSG_ERR(0x1A97, "SDO error : Received response for unknown upload request from nodeId", nodeId);
00869 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
00870 return 0xFF;
00871 }
00872
00873 RestartSDO_TIMER(line)
00874 index = d->transfers[line].index;
00875 subIndex = d->transfers[line].subIndex;
00876
00877 if (getSDOe(m->data[0])) {
00878
00879 nbBytes = 4 - getSDOn2(m->data[0]);
00880
00881 err = SDOtoLine(d, line, nbBytes, (*m).data + 4);
00882 if (err) {
00883 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00884 return 0xFF;
00885 }
00886
00887 MSG_WAR(0x3A98, "SDO expedited upload finished. Response received from node : ", nodeId);
00888 StopSDO_TIMER(line)
00889 d->transfers[line].count = nbBytes;
00890 d->transfers[line].state = SDO_FINISHED;
00891 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
00892 return 0;
00893 }
00894 else {
00895
00896 if (getSDOs(m->data[0])) {
00897 nbBytes = m->data[4];
00898 err = setSDOlineRestBytes(d, line, nbBytes);
00899 if (err) {
00900 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00901 return 0xFF;
00902 }
00903 }
00904
00905 sdo.nodeId = nodeId;
00906 sdo.body.data[0] = 3 << 5;
00907 for (i = 1 ; i < 8 ; i++)
00908 sdo.body.data[i] = 0;
00909 MSG_WAR(0x3A99, "SDO. Sending upload segment request to node : ", nodeId);
00910 sendSDO(d, whoami, sdo);
00911 }
00912 }
00913 break;
00914
00915 case 3:
00916
00917 if (whoami == SDO_SERVER) {
00918
00919
00920 err = getSDOlineOnUse( d, nodeId, whoami, &line );
00921 if (!err)
00922 err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS;
00923 if (err) {
00924 MSG_ERR(0x1AA0, "SDO error : Received upload segment for unstarted trans. index 0x1200 + ",
00925 nodeId);
00926 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
00927 return 0xFF;
00928 }
00929
00930 RestartSDO_TIMER(line)
00931 MSG_WAR(0x3AA1, "Received SDO upload segment defined at index 0x1200 + ", nodeId);
00932 index = d->transfers[line].index;
00933 subIndex = d->transfers[line].subIndex;
00934
00935 if (d->transfers[line].toggle != getSDOt(m->data[0])) {
00936 MSG_ERR(0x1AA2, "SDO error : Toggle error : ", getSDOt(m->data[0]));
00937 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED);
00938 return 0xFF;
00939 }
00940
00941 getSDOlineRestBytes(d, line, &nbBytes);
00942 if (nbBytes > 7) {
00943
00944
00945 sdo.nodeId = nodeId;
00946 sdo.body.data[0] = (d->transfers[line].toggle << 4);
00947 err = lineToSDO(d, line, 7, sdo.body.data + 1);
00948 if (err) {
00949 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00950 return 0xFF;
00951 }
00952
00953 d->transfers[line].toggle = ! d->transfers[line].toggle & 1;
00954 MSG_WAR(0x3AA3, "SDO. Sending upload segment defined at index 0x1200 + ", nodeId);
00955 sendSDO(d, whoami, sdo);
00956 }
00957 else {
00958
00959
00960 sdo.nodeId = nodeId;
00961 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
00962 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
00963 if (err) {
00964 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
00965 return 0xFF;
00966 }
00967 for (i = nbBytes + 1 ; i < 8 ; i++)
00968 sdo.body.data[i] = 0;
00969 MSG_WAR(0x3AA4, "SDO. Sending last upload segment defined at index 0x1200 + ", nodeId);
00970 sendSDO(d, whoami, sdo);
00971
00972 resetSDOline(d, line);
00973 }
00974 }
00975 else {
00976
00977
00978
00979 err = getSDOlineOnUse( d, nodeId, whoami, &line);
00980 if (!err)
00981 err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS;
00982 if (err) {
00983 MSG_ERR(0x1AA5, "SDO error : Received response for unknown download request from nodeId", nodeId);
00984 failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR);
00985 return 0xFF;
00986 }
00987
00988 RestartSDO_TIMER(line)
00989 index = d->transfers[line].index;
00990 subIndex = d->transfers[line].subIndex;
00991
00992 getSDOlineRestBytes(d, line, &nbBytes);
00993 if (nbBytes == 0) {
00994 MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId);
00995 StopSDO_TIMER(line)
00996 d->transfers[line].state = SDO_FINISHED;
00997 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
00998 return 0x00;
00999 }
01000 if (nbBytes > 7) {
01001
01002
01003 sdo.nodeId = nodeId;
01004 sdo.body.data[0] = (d->transfers[line].toggle << 4);
01005 err = lineToSDO(d, line, 7, sdo.body.data + 1);
01006 if (err) {
01007 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
01008 return 0xFF;
01009 }
01010 }
01011 else {
01012
01013
01014 sdo.nodeId = nodeId;
01015 sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1;
01016 err = lineToSDO(d, line, nbBytes, sdo.body.data + 1);
01017 if (err) {
01018 failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR);
01019 return 0xFF;
01020 }
01021 for (i = nbBytes + 1 ; i < 8 ; i++)
01022 sdo.body.data[i] = 0;
01023 }
01024 MSG_WAR(0x3AA7, "SDO sending download segment to nodeId", nodeId);
01025 sendSDO(d, whoami, sdo);
01026
01027 }
01028 break;
01029
01030 case 4:
01031 abortCode = (*m).data[3] |
01032 ((UNS32)m->data[5] << 8) |
01033 ((UNS32)m->data[6] << 16) |
01034 ((UNS32)m->data[7] << 24);
01035
01036
01037 if (whoami == SDO_SERVER) {
01038 err = getSDOlineOnUse( d, nodeId, whoami, &line );
01039 if (!err) {
01040 resetSDOline( d, line );
01041 MSG_WAR(0x3AA8, "SD0. Received SDO abort. Line released. Code : ", abortCode);
01042 }
01043 else
01044 MSG_WAR(0x3AA9, "SD0. Received SDO abort. No line found. Code : ", abortCode);
01045
01046
01047 }
01048 else {
01049 err = getSDOlineOnUse( d, nodeId, whoami, &line );
01050 if (!err) {
01051
01052 StopSDO_TIMER(line)
01053 d->transfers[line].state = SDO_ABORTED_RCV;
01054 d->transfers[line].abortCode = abortCode;
01055 MSG_WAR(0x3AB0, "SD0. Received SDO abort. Line state ABORTED. Code : ", abortCode);
01056 if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId);
01057 }
01058 else
01059 MSG_WAR(0x3AB1, "SD0. Received SDO abort. No line found. Code : ", abortCode);
01060 }
01061 break;
01062 default:
01063
01064 MSG_ERR(0x1AB2, "SDO. Received unknown command specifier : ", getSDOcs(m->data[0]));
01065 return 0xFF;
01066
01067 }
01068 return 0;
01069 }
01070
01071
01072 INLINE UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
01073 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize)
01074 {
01075 UNS8 err;
01076 UNS8 SDOfound = 0;
01077 UNS8 line;
01078 s_SDO sdo;
01079 UNS8 i, j;
01080 UNS16 lastIndex;
01081 UNS16 offset;
01082 UNS32 *pNodeIdServer;
01083 UNS32 nodeIdServer;
01084
01085 MSG_WAR(0x3AC0, "Send SDO to write in the dictionary of node : ", nodeId);
01086 MSG_WAR(0x3AC1, " At index : ", index);
01087 MSG_WAR(0x3AC2, " subIndex : ", subIndex);
01088 MSG_WAR(0x3AC3, " nb bytes : ", count);
01089
01090
01091 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
01092 if (!err) {
01093 MSG_ERR(0x1AC4, "SDO error : Communication yet established. with node : ", nodeId);
01094 return 0xFF;
01095 }
01096
01097 err = getSDOfreeLine( d, SDO_CLIENT, &line );
01098 if (err) {
01099 MSG_ERR(0x1AC5, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
01100 return (0xFF);
01101 }
01102
01103 offset = d->firstIndex->SDO_CLT;
01104 lastIndex = d->lastIndex->SDO_CLT;
01105 if (offset == 0) {
01106 MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0);
01107 return 0xFF;
01108 }
01109 i = 0;
01110 while (offset <= lastIndex) {
01111 if (d->objdict[offset].bSubCount <= 3) {
01112 MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i);
01113 return 0xFF;
01114 }
01115
01116 pNodeIdServer = d->objdict[offset].pSubindex[3].pObject;
01117 nodeIdServer = *pNodeIdServer;
01118 MSG_WAR(0x1AD2, "index : ", 0x1280 + i);
01119 MSG_WAR(0x1AD3, "nodeIdServer : ", nodeIdServer);
01120
01121 if(nodeIdServer == (UNS32)nodeId) {
01122 SDOfound = 1;
01123 break;
01124 }
01125 offset++;
01126 i++;
01127 }
01128 if (!SDOfound) {
01129 MSG_ERR(0x1AC9, "SDO. Error. No client found to communicate with node : ", nodeId);
01130 return 0xFF;
01131 }
01132 MSG_WAR(0x3AD0," SDO client defined at index : ", 0x1280 + i);
01133 initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS);
01134 d->transfers[line].count = count;
01135 d->transfers[line].dataType = dataType;
01136
01137
01138 for (j = 0 ; j < count ; j++) {
01139 # ifdef CANOPEN_BIG_ENDIAN
01140 if (dataType == 0 && endianize)
01141 d->transfers[line].data[count - 1 - j] = ((char *)data)[j];
01142 else
01143 d->transfers[line].data[j] = ((char *)data)[j];
01144 # else
01145 d->transfers[line].data[j] = ((char *)data)[j];
01146 # endif
01147 }
01148
01149 sdo.nodeId = nodeId;
01150 if (count <= 4) {
01151 sdo.body.data[0] = (1 << 5) | ((4 - count) << 2) | 3;
01152 for (i = 4 ; i < 8 ; i++)
01153 sdo.body.data[i] = d->transfers[line].data[i - 4];
01154 d->transfers[line].offset = count;
01155 }
01156 else {
01157 sdo.body.data[0] = (1 << 5) | 1;
01158 sdo.body.data[4] = count;
01159 for (i = 5 ; i < 8 ; i++)
01160 sdo.body.data[i] = 0;
01161 }
01162 sdo.body.data[1] = index & 0xFF;
01163 sdo.body.data[2] = (index >> 8) & 0xFF;
01164 sdo.body.data[3] = subIndex;
01165
01166 d->transfers[line].Callback = Callback;
01167
01168 err = sendSDO(d, SDO_CLIENT, sdo);
01169 if (err) {
01170 MSG_ERR(0x1AD1, "SDO. Error while sending SDO to node : ", nodeId);
01171
01172 resetSDOline(d, line);
01173 return 0xFF;
01174 }
01175
01176
01177 return 0;
01178 }
01179
01180
01181
01182 UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
01183 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data)
01184 {
01185 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, NULL, 1);
01186 }
01187
01188
01189
01190 UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index,
01191 UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback)
01192 {
01193 return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback, 1);
01194 }
01195
01196
01197
01198 INLINE UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
01199 {
01200 UNS8 err;
01201 UNS8 SDOfound = 0;
01202 UNS8 i;
01203 UNS8 line;
01204 s_SDO sdo;
01205 UNS32 *pNodeIdServer;
01206 UNS32 nodeIdServer;
01207 UNS16 offset;
01208 UNS16 lastIndex;
01209 MSG_WAR(0x3AD5, "Send SDO to read in the dictionary of node : ", nodeId);
01210 MSG_WAR(0x3AD6, " At index : ", index);
01211 MSG_WAR(0x3AD7, " subIndex : ", subIndex);
01212
01213
01214
01215 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
01216 if (!err) {
01217 MSG_ERR(0x1AD8, "SDO error : Communication yet established. with node : ", nodeId);
01218 return 0xFF;
01219 }
01220
01221 err = getSDOfreeLine( d, SDO_CLIENT, &line );
01222 if (err) {
01223 MSG_ERR(0x1AD9, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId);
01224 return (0xFF);
01225 }
01226 else
01227 MSG_WAR(0x3AE0, "Transmission on line : ", line);
01228
01229
01230 offset = d->firstIndex->SDO_CLT;
01231 lastIndex = d->lastIndex->SDO_CLT;
01232 if (offset == 0) {
01233 MSG_ERR(0x1AE1, "writeNetworkDict : No SDO client index found", 0);
01234 return 0xFF;
01235 }
01236 i = 0;
01237 while (offset <= lastIndex) {
01238 if (d->objdict[offset].bSubCount <= 3) {
01239 MSG_ERR(0x1AE2, "Subindex 3 not found at index ", 0x1280 + i);
01240 return 0xFF;
01241 }
01242
01243 pNodeIdServer = d->objdict[offset].pSubindex[3].pObject;
01244 nodeIdServer = *pNodeIdServer;
01245
01246 if(nodeIdServer == (UNS32)nodeId) {
01247 SDOfound = 1;
01248 break;
01249 }
01250 offset++;
01251 i++;
01252 }
01253 if (!SDOfound) {
01254 MSG_ERR(0x1AE3, "SDO. Error. No client found to communicate with node : ", nodeId);
01255 return 0xFF;
01256 }
01257 MSG_WAR(0x3AE4," SDO client defined at index : ", 0x1280 + i);
01258 initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS);
01259 getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
01260 sdo.nodeId = nodeId;
01261
01262 d->transfers[line].dataType = dataType;
01263 sdo.body.data[0] = (2 << 5);
01264 sdo.body.data[1] = index & 0xFF;
01265 sdo.body.data[2] = (index >> 8) & 0xFF;
01266 sdo.body.data[3] = subIndex;
01267 for (i = 4 ; i < 8 ; i++)
01268 sdo.body.data[i] = 0;
01269 d->transfers[line].Callback = Callback;
01270 err = sendSDO(d, SDO_CLIENT, sdo);
01271 if (err) {
01272 MSG_ERR(0x1AE5, "SDO. Error while sending SDO to node : ", nodeId);
01273
01274 resetSDOline(d, line);
01275 return 0xFF;
01276 }
01277 return 0;
01278 }
01279
01280
01281
01282 UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType)
01283 {
01284 return _readNetworkDict (d, nodeId, index, subIndex, dataType, NULL);
01285 }
01286
01287
01288 UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback)
01289 {
01290 return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback);
01291 }
01292
01293
01294
01295 UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size,
01296 UNS32 * abortCode)
01297 {
01298 UNS8 i;
01299 UNS8 err;
01300 UNS8 line;
01301 * size = 0;
01302
01303
01304 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
01305 if (err) {
01306 MSG_ERR(0x1AF0, "SDO error : No line found for communication with node : ", nodeId);
01307 return SDO_ABORTED_INTERNAL;
01308 }
01309 if (d->transfers[line].state != SDO_FINISHED)
01310 return d->transfers[line].state;
01311
01312
01313 * size = (UNS8)d->transfers[line].count;
01314 for ( i = 0 ; i < *size ; i++) {
01315 # ifdef CANOPEN_BIG_ENDIAN
01316 if (d->transfers[line].dataType != visible_string)
01317 ( (char *) data)[*size - 1 - i] = d->transfers[line].data[i];
01318 else
01319 ( (char *) data)[i] = d->transfers[line].data[i];
01320 # else
01321 ( (char *) data)[i] = d->transfers[line].data[i];
01322 # endif
01323 }
01324 return SDO_FINISHED;
01325 }
01326
01327
01328
01329 UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode)
01330 {
01331 UNS8 line = 0;
01332 UNS8 err;
01333
01334 * abortCode = 0;
01335
01336 err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line);
01337 if (err) {
01338 MSG_ERR(0x1AF1, "SDO error : No line found for communication with node : ", nodeId);
01339 return SDO_ABORTED_INTERNAL;
01340 }
01341 * abortCode = d->transfers[line].abortCode;
01342 return d->transfers[line].state;
01343 }