use of org.apache.plc4x.java.canopen.transport.CANOpenAbortException in project plc4x by apache.
the class SDODownloadConversation method execute.
public void execute(CompletableFuture<PlcResponseCode> receiver) {
if (data.length > 4) {
// segmented
SDOInitiateSegmentedUploadResponse size = new SDOInitiateSegmentedUploadResponse(data.length, (byte) 0);
delegate.send(createFrame(new SDOInitiateDownloadRequest(false, true, indexAddress, size))).check(new NodeIdPredicate(answerNodeId)).onTimeout(receiver::completeExceptionally).onError((response, error) -> receiver.completeExceptionally(error)).unwrap(CANOpenFrame::getPayload).only(CANOpenSDOResponse.class).unwrap(CANOpenSDOResponse::getResponse).check(new TypeOrAbortPredicate<>(SDOInitiateDownloadResponse.class)).unwrap(payload -> unwrap(SDOInitiateDownloadResponse.class, payload)).handle(either -> {
if (either.isLeft()) {
receiver.completeExceptionally(new CANOpenAbortException("Could not initiate upload", either.getLeft().getCode()));
} else {
SDOInitiateDownloadResponse response = either.get();
if (response.getAddress().equals(indexAddress)) {
put(data, receiver, false, 0);
} else {
// TODO find proper error code in spec
SDOAbort abort = new SDOAbort(indexAddress, 1000);
delegate.sendToWire(createFrame(new SDOAbortRequest(abort)));
receiver.complete(PlcResponseCode.REMOTE_ERROR);
}
}
});
return;
}
// expedited
SDOInitiateDownloadRequest rq = new SDOInitiateDownloadRequest(true, true, indexAddress, new SDOInitiateExpeditedUploadResponse(data, (byte) 0));
delegate.send(createFrame(rq)).check(new NodeIdPredicate(answerNodeId)).onTimeout(receiver::completeExceptionally).unwrap(CANOpenFrame::getPayload).only(CANOpenSDOResponse.class).onError((response, error) -> onError(receiver, response, error)).unwrap(CANOpenSDOResponse::getResponse).check(new TypeOrAbortPredicate<>(SDOInitiateDownloadResponse.class)).unwrap(payload -> unwrap(SDOInitiateDownloadResponse.class, payload)).handle(either -> {
if (either.isLeft()) {
receiver.completeExceptionally(new CANOpenAbortException("Could not initiate upload", either.getLeft().getCode()));
} else {
SDOInitiateDownloadResponse response = either.get();
if (response.getCommand() == SDOResponseCommand.INITIATE_DOWNLOAD) {
receiver.complete(PlcResponseCode.OK);
} else {
receiver.complete(PlcResponseCode.REMOTE_ERROR);
}
}
});
}
use of org.apache.plc4x.java.canopen.transport.CANOpenAbortException in project plc4x by apache.
the class SDOUploadConversation method fetch.
private void fetch(ByteStorage.SDOUploadStorage storage, BiConsumer<Integer, byte[]> valueCallback, CompletableFuture<PlcValue> receiver, boolean toggle, int size) {
logger.info("Request next data block for address {}/{}", Integer.toHexString(address.getIndex()), Integer.toHexString(address.getSubindex()));
delegate.send(createFrame(new SDOSegmentUploadRequest(toggle))).check(new NodeIdPredicate(answerNodeId)).onTimeout(receiver::completeExceptionally).unwrap(CANOpenFrame::getPayload).only(CANOpenSDOResponse.class).onError((payload, error) -> onError(receiver, payload, error)).unwrap(CANOpenSDOResponse::getResponse).check(new TypeOrAbortPredicate<>(SDOSegmentUploadResponse.class)).unwrap(payload -> unwrap(SDOSegmentUploadResponse.class, payload)).handle(either -> {
if (either.isLeft()) {
SDOAbort abort = either.getLeft();
receiver.completeExceptionally(new CANOpenAbortException("Could not complete operation", abort.getCode()));
} else {
SDOSegmentUploadResponse response = either.get();
if (response.getToggle() != toggle) {
// TODO find proper error code in specs
receiver.completeExceptionally(new CANOpenAbortException("Remote operation failed", 1000));
SDOAbort abort = new SDOAbort(address, 1000);
delegate.sendToWire(createFrame(new SDOAbortRequest(abort)));
return;
}
storage.append(either.get());
if (response.getLast()) {
// validate size
logger.trace("Completed reading of data from {}/{}, collected {}, wanted {}", Integer.toHexString(address.getIndex()), Integer.toHexString(address.getSubindex()), storage.size(), size);
valueCallback.accept(Long.valueOf(size).intValue(), storage.get());
} else {
logger.trace("Continue reading of data from {}/{}, collected {}, wanted {}", Integer.toHexString(address.getIndex()), Integer.toHexString(address.getSubindex()), storage.size(), size);
fetch(storage, valueCallback, receiver, !toggle, size);
}
}
});
}
use of org.apache.plc4x.java.canopen.transport.CANOpenAbortException in project plc4x by apache.
the class CANOpenProtocolLogic method readInternally.
private void readInternally(PlcReadRequest readRequest, CANOpenSDOField field, CompletableFuture<PlcReadResponse> response) {
String fieldName = readRequest.getFieldNames().iterator().next();
final RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
CompletableFuture<PlcValue> callback = new CompletableFuture<>();
callback.whenComplete((value, error) -> {
if (error != null) {
Map<String, ResponseItem<PlcValue>> fields = new HashMap<>();
if (error instanceof CANOpenAbortException) {
fields.put(fieldName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, new PlcLINT(((CANOpenAbortException) error).getAbortCode())));
} else {
fields.put(fieldName, new ResponseItem<>(PlcResponseCode.REMOTE_ERROR, null));
}
response.complete(new DefaultPlcReadResponse(readRequest, fields));
transaction.endRequest();
return;
}
Map<String, ResponseItem<PlcValue>> fields = new HashMap<>();
fields.put(fieldName, new ResponseItem<>(PlcResponseCode.OK, value));
response.complete(new DefaultPlcReadResponse(readRequest, fields));
transaction.endRequest();
});
SDOUploadConversation upload = new SDOUploadConversation(conversation, field.getNodeId(), field.getAnswerNodeId(), new IndexAddress(field.getIndex(), field.getSubIndex()), field.getCanOpenDataType());
transaction.submit(() -> upload.execute(callback));
}
use of org.apache.plc4x.java.canopen.transport.CANOpenAbortException in project plc4x by apache.
the class CANOpenProtocolLogic method writeInternally.
private void writeInternally(DefaultPlcWriteRequest writeRequest, CANOpenSDOField field, CompletableFuture<PlcWriteResponse> response) {
final RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
String fieldName = writeRequest.getFieldNames().iterator().next();
CompletableFuture<PlcResponseCode> callback = new CompletableFuture<>();
callback.whenComplete((code, error) -> {
if (error != null) {
if (error instanceof CANOpenAbortException) {
response.complete(new DefaultPlcWriteResponse(writeRequest, Collections.singletonMap(fieldName, PlcResponseCode.REMOTE_ERROR)));
} else {
response.complete(new DefaultPlcWriteResponse(writeRequest, Collections.singletonMap(fieldName, PlcResponseCode.INTERNAL_ERROR)));
}
transaction.endRequest();
return;
}
response.complete(new DefaultPlcWriteResponse(writeRequest, Collections.singletonMap(fieldName, code)));
transaction.endRequest();
});
PlcValue writeValue = writeRequest.getPlcValues().get(0);
SDODownloadConversation download = new SDODownloadConversation(conversation, field.getNodeId(), field.getAnswerNodeId(), new IndexAddress(field.getIndex(), field.getSubIndex()), writeValue, field.getCanOpenDataType());
transaction.submit(() -> download.execute(callback));
}
use of org.apache.plc4x.java.canopen.transport.CANOpenAbortException in project plc4x by apache.
the class SDOUploadConversation method execute.
public void execute(CompletableFuture<PlcValue> receiver) {
SDOInitiateUploadRequest rq = new SDOInitiateUploadRequest(address);
delegate.send(createFrame(rq)).check(new NodeIdPredicate(answerNodeId)).onTimeout(receiver::completeExceptionally).unwrap(CANOpenFrame::getPayload).only(CANOpenSDOResponse.class).onError((payload, error) -> onError(receiver, payload, error)).unwrap(CANOpenSDOResponse::getResponse).check(new TypeOrAbortPredicate<>(SDOInitiateUploadResponse.class)).unwrap(payload -> unwrap(SDOInitiateUploadResponse.class, payload)).check(either -> either.isLeft() || either.get().getAddress().equals(address)).handle(either -> {
if (either.isLeft()) {
SDOAbort abort = either.getLeft();
receiver.completeExceptionally(new CANOpenAbortException("Could not complete operation", abort.getCode()));
} else {
handle(receiver, either.get());
}
});
}
Aggregations