merge -c1622 branches/1.4-foe: Fixed seg_size parameter when processing an CoE Upload Segment Response. stable-1.4
authorFlorian Pose <fp@igh-essen.com>
Mon, 26 Jan 2009 14:17:01 +0000
branchstable-1.4
changeset 1696 c9bfe98e00d5
parent 1695 69a948e240df
child 1697 5958adc4300a
merge -c1622 branches/1.4-foe: Fixed seg_size parameter when processing an CoE Upload Segment Response.
master/fsm_coe.c
master/fsm_coe.h
--- a/master/fsm_coe.c	Mon Jan 19 10:23:26 2009 +0000
+++ b/master/fsm_coe.c	Mon Jan 26 14:17:01 2009 +0000
@@ -1485,7 +1485,6 @@
     uint8_t *data, mbox_prot;
     size_t rec_size, data_size;
     ec_sdo_request_t *request = fsm->request;
-    uint32_t complete_size;
     unsigned int expedited, size_specified;
 
     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
@@ -1583,12 +1582,12 @@
 
         size_specified = EC_READ_U8(data + 2) & 0x01;
         if (size_specified) {
-            complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
+            fsm->complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2);
         } else {
-            complete_size = 4;
-        }
-
-        if (rec_size < 6 + complete_size) {
+            fsm->complete_size = 4;
+        }
+
+        if (rec_size < 6 + fsm->complete_size) {
             fsm->state = ec_fsm_coe_error;
             EC_ERR("Received currupted SDO expedited upload"
                     " response (only %u bytes)!\n", rec_size);
@@ -1596,7 +1595,7 @@
             return;
         }
 
-        if (ec_sdo_request_copy_data(request, data + 6, complete_size)) {
+        if (ec_sdo_request_copy_data(request, data + 6, fsm->complete_size)) {
             fsm->state = ec_fsm_coe_error;
             return;
         }
@@ -1626,16 +1625,16 @@
         }
 
         data_size = rec_size - 10;
-        complete_size = EC_READ_U32(data + 6);
-
-        if (!complete_size) {
+        fsm->complete_size = EC_READ_U32(data + 6);
+
+        if (!fsm->complete_size) {
             fsm->state = ec_fsm_coe_error;
             EC_ERR("No complete size supplied!\n");
             ec_print_data(data, rec_size);
             return;
         }
 
-        if (ec_sdo_request_alloc(request, complete_size)) {
+        if (ec_sdo_request_alloc(request, fsm->complete_size)) {
             fsm->state = ec_fsm_coe_error;
             return;
         }
@@ -1647,9 +1646,10 @@
 
         fsm->toggle = 0;
 
-        if (data_size < complete_size) {
-            EC_WARN("SDO data incomplete (%u / %u).\n",
-                    data_size, complete_size);
+        if (data_size < fsm->complete_size) {
+            if (master->debug_level)
+                EC_DBG("SDO data incomplete (%u / %u). Segmenting...\n",
+                        data_size, fsm->complete_size);
 
             if (!(data = ec_slave_mbox_prepare_send(slave, datagram,
                                                     0x03, 3))) {
@@ -1774,7 +1774,6 @@
 /**
    CoE state: UP RESPONSE.
    \todo Timeout behavior
-   \todo Check for \a data_size exceeding \a complete_size.
 */
 
 void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *fsm /**< finite state machine */)
@@ -1865,12 +1864,19 @@
 
     last_segment = EC_READ_U8(data + 2) & 0x01;
     seg_size = (EC_READ_U8(data + 2) & 0xE) >> 1;
-    data_size = rec_size - 10;
-
-    if (data_size != seg_size) {
-        EC_WARN("SDO segment data invalid (%u / %u)"
-                " - Fragmenting not implemented.\n",
-                data_size, seg_size);
+    if (rec_size > 10) {
+        data_size = rec_size - 10;
+    } else { // == 10
+        /* seg_size contains the number of trailing bytes to ignore. */
+        data_size = rec_size - seg_size;
+    }
+
+    if (request->data_size + data_size > fsm->complete_size) {
+        EC_ERR("SDO upload 0x%04X:%02X failed on slave %u: Fragment"
+                " exceeding complete size!\n",
+               request->index, request->subindex, slave->ring_position);
+        fsm->state = ec_fsm_coe_error;
+        return;
     }
 
     memcpy(request->data + request->data_size, data + 10, data_size);
@@ -1898,6 +1904,13 @@
         return;
     }
 
+    if (request->data_size != fsm->complete_size) {
+        EC_WARN("SDO upload 0x%04X:%02X on slave %u: Assembled data"
+                " size (%u) does not match complete size (%u)!\n",
+                request->index, request->subindex, slave->ring_position,
+                request->data_size, fsm->complete_size);
+    }
+
     if (master->debug_level) {
         EC_DBG("Uploaded data:\n");
         ec_print_data(request->data, request->data_size);
--- a/master/fsm_coe.h	Mon Jan 19 10:23:26 2009 +0000
+++ b/master/fsm_coe.h	Mon Jan 26 14:17:01 2009 +0000
@@ -57,6 +57,7 @@
     ec_sdo_t *sdo; /**< current SDO */
     uint8_t subindex; /**< current subindex */
     ec_sdo_request_t *request; /**< SDO request */
+    uint32_t complete_size; /**< Used when segmenting. */
     uint8_t toggle; /**< toggle bit for segment commands */
 };