109 lines
2.7 KiB
C
109 lines
2.7 KiB
C
#include <CommandBuffer.h>
|
|
#include <Logger.h>
|
|
|
|
#include <Buffer.h>
|
|
#include <Image.h>
|
|
|
|
static const char* CommandName[] = {
|
|
"CopyBuffer", "FillBuffer", "CopyBufferToImage", "CopyImageToBuffer", "CopyImage",
|
|
};
|
|
|
|
PhiStatus ReadCommandData(PhiCommandReader* reader, void* data, uint64_t size)
|
|
{
|
|
if(reader->remaining < size)
|
|
return PHI_STATUS_BAD_MESSAGE;
|
|
|
|
if(ReadAll(reader->endpoint, data, (size_t)size) < 0)
|
|
return PHI_STATUS_BAD_MESSAGE;
|
|
|
|
reader->remaining -= size;
|
|
return PHI_STATUS_OK;
|
|
}
|
|
|
|
int DrainCommandReader(PhiCommandReader* reader)
|
|
{
|
|
if(reader->remaining == 0)
|
|
return 0;
|
|
|
|
int result = DrainPayload(reader->endpoint, reader->remaining);
|
|
reader->remaining = 0;
|
|
return result;
|
|
}
|
|
|
|
static PhiStatus ReadCommandHeader(PhiCommandReader* reader, PhiCmdHeader* command_header)
|
|
{
|
|
PhiStatus status = ReadCommandData(reader, command_header, sizeof(*command_header));
|
|
if(status != PHI_STATUS_OK)
|
|
return status;
|
|
|
|
if(command_header->magic != PHI_COMMAND_MAGIC)
|
|
return PHI_STATUS_BAD_MESSAGE;
|
|
|
|
return PHI_STATUS_OK;
|
|
}
|
|
|
|
static PhiStatus ExecuteCommand(PhiCommandReader* reader, const PhiCmdHeader* command_header)
|
|
{
|
|
if(IsBufferCommand(command_header))
|
|
return ExecuteBufferCommand(reader, command_header);
|
|
|
|
if(IsImageCommand(command_header))
|
|
return ExecuteImageCommand(reader, command_header);
|
|
|
|
return PHI_STATUS_BAD_MESSAGE;
|
|
}
|
|
|
|
int HandleWorkExecution(PhiEndpoint endpoint, const PhiMessageHeader* header)
|
|
{
|
|
PhiWorkExecutionRequest request;
|
|
PhiResultReply reply = {
|
|
.result = {
|
|
.status = PHI_STATUS_OK,
|
|
.reserved = 0,
|
|
},
|
|
};
|
|
|
|
if(header->payload_size < sizeof(request))
|
|
{
|
|
if(DrainPayload(endpoint, header->payload_size) < 0)
|
|
return -1;
|
|
reply.result.status = PHI_STATUS_BAD_MESSAGE;
|
|
return SendReply(endpoint, header, &reply, sizeof(reply));
|
|
}
|
|
if(ReadAll(endpoint, &request, sizeof(request)) < 0)
|
|
return -1;
|
|
|
|
PhiCommandReader reader = {
|
|
.endpoint = endpoint,
|
|
.remaining = header->payload_size - sizeof(request),
|
|
};
|
|
|
|
if(reader.remaining != request.command_buffer_size)
|
|
{
|
|
if(DrainCommandReader(&reader) < 0)
|
|
return -1;
|
|
reply.result.status = PHI_STATUS_BAD_MESSAGE;
|
|
return SendReply(endpoint, header, &reply, sizeof(reply));
|
|
}
|
|
|
|
for(uint64_t cmd_index = 0; cmd_index < request.cmd_count; ++cmd_index)
|
|
{
|
|
PhiCmdHeader cmd_header;
|
|
reply.result.status = ReadCommandHeader(&reader, &cmd_header);
|
|
if(reply.result.status != PHI_STATUS_OK)
|
|
break;
|
|
|
|
reply.result.status = ExecuteCommand(&reader, &cmd_header);
|
|
if(reply.result.status != PHI_STATUS_OK)
|
|
{
|
|
LogErrorFmt("Command %s execution failed: %s", CommandName[cmd_header.type], StatusName[reply.result.status]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(reader.remaining > 0 && DrainCommandReader(&reader) < 0)
|
|
return -1;
|
|
|
|
return SendReply(endpoint, header, &reply, sizeof(reply));
|
|
}
|