# HG changeset patch # User Florian Pose # Date 1232448599 0 # Node ID 45ff770312550f31aae159c55c692a4764e03abb # Parent 2b017fcc1c6dc276ab018eb2a7081b60531d9156 Fixed seg_size parameter when processing an CoE Upload Segment Response. diff -r 2b017fcc1c6d -r 45ff77031255 master/fsm_coe.c --- a/master/fsm_coe.c Tue Jan 20 09:55:32 2009 +0000 +++ b/master/fsm_coe.c Tue Jan 20 10:49:59 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); diff -r 2b017fcc1c6d -r 45ff77031255 master/fsm_coe.h --- a/master/fsm_coe.h Tue Jan 20 09:55:32 2009 +0000 +++ b/master/fsm_coe.h Tue Jan 20 10:49:59 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 */ };