26 *(uint32_t*)
this = val;
42 uint8_t size_indicated:1;
52 if(expedited && size_indicated)
return 4-num;
53 else if(!expedited && size_indicated)
return payload[0] | (payload[3]<<8);
57 size_t size = buffer.size();
61 payload[0] = size & 0xFF;
62 payload[3] = (size >> 8) & 0xFF;
68 memcpy(payload, buffer.data(), size);
91 size_t size = buffer.size() - offset;
92 if(size > 7) size = 7;
95 memcpy(payload, buffer.data() + offset, size);
101 static const uint8_t command = 1;
104 data.command = command;
105 data.index = entry.
index;
107 offset = data.apply_buffer(buffer);
113 static const uint8_t command = 3;
128 static const uint8_t command = 0;
133 data.command = command;
134 data.toggle = toggle?1:0;
135 offset = data.apply_buffer(buffer, offset);
140 static const uint8_t command = 1;
157 static const uint8_t command = 2;
159 data.command = command;
160 data.index = entry.
index;
167 static const uint8_t command = 2;
172 size_t ds = data.data_size();
173 if(ds == 0 || size == 0 || ds >= size) {
174 if(!data.expedited || (ds <= 4 && size <= 4))
return true;
184 if(data.size_indicated && total == 0){
185 total = data.data_size();
186 buffer.resize(total);
189 memcpy(&buffer.front(), data.payload, buffer.size());
190 offset = buffer.size();
197 static const uint8_t command = 3;
199 data.command = command;
200 data.toggle = toggle?1:0;
206 static const uint8_t command = 0;
221 uint32_t n = data.data_size();
223 buffer.resize(offset + n);
225 if(offset + n <= buffer.size()){
226 memcpy(&buffer[offset], data.payload, n);
243 case 0x05030000:
return "Toggle bit not alternated.";
244 case 0x05040000:
return "SDO protocol timed out.";
245 case 0x05040001:
return "Client/server command specifier not valid or unknown.";
246 case 0x05040002:
return "Invalid block size (block mode only).";
247 case 0x05040003:
return "Invalid sequence number (block mode only).";
248 case 0x05040004:
return "CRC error (block mode only).";
249 case 0x05040005:
return "Out of memory.";
250 case 0x06010000:
return "Unsupported access to an object.";
251 case 0x06010001:
return "Attempt to read a write only object.";
252 case 0x06010002:
return "Attempt to write a read only object.";
253 case 0x06020000:
return "Object does not exist in the object dictionary.";
254 case 0x06040041:
return "Object cannot be mapped to the PDO.";
255 case 0x06040042:
return "The number and length of the objects to be mapped would exceed PDO length.";
256 case 0x06040043:
return "General parameter incompatibility reason.";
257 case 0x06040047:
return "General internal incompatibility in the device.";
258 case 0x06060000:
return "Access failed due to an hardware error.";
259 case 0x06070010:
return "Data type does not match, length of service parameter does not match";
260 case 0x06070012:
return "Data type does not match, length of service parameter too high";
261 case 0x06070013:
return "Data type does not match, length of service parameter too low";
262 case 0x06090011:
return "Sub-index does not exist.";
263 case 0x06090030:
return "Invalid value for parameter (download only).";
264 case 0x06090031:
return "Value of parameter written too high (download only).";
265 case 0x06090032:
return "Value of parameter written too low (download only).";
266 case 0x06090036:
return "Maximum value is less than minimum value.";
267 case 0x060A0023:
return "Resource not available: SDO connection";
268 case 0x08000000:
return "General error";
269 case 0x08000020:
return "Data cannot be transferred or stored to the application.";
270 case 0x08000021:
return "Data cannot be transferred or stored to the application because of local control.";
271 case 0x08000022:
return "Data cannot be transferred or stored to the application because of the present device state.";
272 case 0x08000023:
return "Object dictionary dynamic generation fails or no object dictionary is present (e.g.object dictionary is generated from file and generation fails because of an file error).";
273 case 0x08000024:
return "No data available";
274 default:
return "Abort code is reserved";
280 static const uint8_t command = 4;
283 data.command = command;
285 data.sub_index = sub_index;
286 data.reason = reason;
294 interface_->send(last_msg =
AbortTranserRequest(client_id, current_entry->index, current_entry->sub_index, reason));
299 if(msg.
dlc != 8)
return false;
302 switch(msg.
data[0] >> 5){
306 if(resp.
test(last_msg, reason) ){
318 if( resp.
test(last_msg, reason) ){
331 if( resp.
test(last_msg, total, reason) ){
332 if(resp.
read_data(buffer, offset, total)){
343 if( resp.
test(last_msg, reason) ){
344 if(resp.
read_data(buffer, offset, total)){
345 if(resp.
data.
done || offset == total){
352 LOG(
"abort, size mismatch" << buffer.size() <<
" " << resp.
data.
data_size());
395 reader_.listen(interface_, server_id);
401 total = buffer.size();
402 current_entry = &entry;
413 boost::this_thread::disable_interruption di;
417 if(!reader_.read(&msg,boost::chrono::seconds(1)))
420 LOG(
"Did not receive a response message");
423 if(!processFrame(msg)){
424 LOG(
"Could not process message");
428 if(offset == 0 || offset != total){
432 if(result) *result=buffer;
437 boost::timed_mutex::scoped_lock lock(mutex, boost::chrono::seconds(2));
439 transmitAndWait(entry, data, &data);
445 boost::timed_mutex::scoped_lock lock(mutex, boost::chrono::seconds(2));
447 transmitAndWait(entry, data, 0);
size_t apply_buffer(const String &buffer)
void read(const canopen::ObjectDict::Entry &entry, String &data)
bool test(const can::Frame &msg, uint32_t &reason)
UploadInitiateResponse(const can::Frame &f)
boost::unordered_map< Key, EntryConstSharedPtr > dict_
UploadInitiateRequest(const can::Frame &f)
const uint8_t INITIATE_UPLOAD_RESPONSE
UploadInitiateRequest(const Header &h, const canopen::ObjectDict::Entry &entry)
const uint8_t DOWNLOAD_SEGMENT_REQUEST
bool read_data(String &buffer, size_t &offset, const size_t &total)
const uint8_t ABORT_TRANSFER_REQUEST
const uint8_t UPLOAD_SEGMENT_REQUEST
DownloadInitiateRequest(const can::Frame &f)
const uint8_t INITIATE_DOWNLOAD_REQUEST
boost::array< value_type, 8 > data
const uint8_t INITIATE_UPLOAD_REQUEST
static const uint8_t command
static const uint8_t command
void transmitAndWait(const canopen::ObjectDict::Entry &entry, const String &data, String *result)
DownloadInitiateRequest(const Header &h, const canopen::ObjectDict::Entry &entry, const String &buffer, size_t &offset)
DownloadSegmentResponse(const can::Frame &f)
static const uint8_t command
const uint8_t UPLOAD_SEGMENT_RESPONSE
DownloadInitiateResponse(const can::Frame &f)
UploadSegmentRequest(const can::Frame &f)
bool test(const can::Frame &msg, uint32_t &reason)
static const uint8_t command
UploadSegmentRequest(const Header &h, bool toggle)
UploadSegmentResponse(const can::Frame &f)
bool test(const can::Frame &msg, size_t size, uint32_t &reason)
static const uint8_t command
bool processFrame(const can::Frame &msg)
DownloadSegmentRequest(const Header &h, bool toggle, const String &buffer, size_t &offset)
void write(const canopen::ObjectDict::Entry &entry, const String &data)
static const uint8_t command
DownloadSegmentRequest(const can::Frame &f)
static const uint8_t command
AbortTranserRequest(const can::Frame &f)
AbortTranserRequest(const Header &h, uint16_t index, uint8_t sub_index, uint32_t reason)
static const uint8_t command
bool test(const can::Frame &msg, uint32_t &reason)
const uint8_t INITIATE_DOWNLOAD_RESPONSE
void abort(uint32_t reason)
bool read_data(String &buffer, size_t &offset, size_t &total)
#define THROW_WITH_KEY(e, k)
const uint8_t COMMAND_MASK
static const uint8_t command
size_t apply_buffer(const String &buffer, const size_t offset)
const uint8_t DOWNLOAD_SEGMENT_RESPONSE