Enabled arcs render after adapting OpenCNCPilot code.

Started porting iosender to C++
This commit is contained in:
2023-05-16 09:18:06 +03:00
parent c05a6a1ad2
commit 42aefe8ed8
23 changed files with 2200 additions and 18 deletions
+199
View File
@@ -0,0 +1,199 @@
#include "telnet.h"
#include "../string_utils.h"
#include "grbl.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <fcntl.h>
#include <chrono>
bool iosender::TelnetStream::IsOpen() {
return fd > 0 && isConnected;
}
int iosender::TelnetStream::OutCount() {
return 0;
}
std::string iosender::TelnetStream::Reply() {
return reply;
}
iosender::Comms::StreamType iosender::TelnetStream::StreamType() {
return Comms::StreamType::Telnet;
}
bool iosender::TelnetStream::EventMode() {
return eventMode;
}
void iosender::TelnetStream::EventMode(bool mode) {
eventMode = mode;
}
void iosender::TelnetStream::Close() {
shouldQuit = true;
workerThread.join();
}
int iosender::TelnetStream::ReadByte() {
return 0;
}
void iosender::TelnetStream::WriteByte(uint8_t data) {
auto result = write(fd, &data, 1);
if (result == -1) {
std::cerr << "Failed while writing." << std::endl;
}
}
void iosender::TelnetStream::WriteBytes(uint8_t *bytes, int len) {
ssize_t written_bytes = 0;
for (; written_bytes < len;) {
auto result = write(fd, &bytes, len);
if (result == -1) {
std::cerr << "Failed while writing." << std::endl;
return;
}
written_bytes += result;
}
}
void iosender::TelnetStream::WriteString(std::string data) {
WriteBytes(reinterpret_cast<uint8_t *>(data.data()), data.size());
}
void iosender::TelnetStream::WriteCommand(std::string command) {
CommandState = Comms::State::AwaitAck;
if (command.size() == 1 && command != GrblConstants::CMD_PROGRAM_DEMARCATION) {
WriteByte(*command.data());
} else {
command += "\r";
WriteString(command);
}
}
std::string iosender::TelnetStream::GetReply(std::string command) {
reply = "";
AwaitResponse(command);
return reply;
}
void iosender::TelnetStream::AwaitAck() {
while (Comms::GetCom()->CommandState == Comms::State::DataReceived ||
Comms::GetCom()->CommandState == Comms::State::AwaitAck) {
std::this_thread::sleep_for(std::chrono::microseconds(500));
}
}
void iosender::TelnetStream::AwaitAck(std::string command) {
WriteCommand(command);
AwaitAck();
}
void iosender::TelnetStream::AwaitResponse() {
while (Comms::GetCom()->CommandState == Comms::State::AwaitAck) {
std::this_thread::sleep_for(std::chrono::microseconds(500));
}
}
void iosender::TelnetStream::AwaitResponse(std::string command) {
WriteCommand(command);
AwaitResponse();
}
void iosender::TelnetStream::PurgeQueue() {
}
iosender::TelnetStream::TelnetStream(std::string host, iosender::DataReceivedHandler *dataHandler,
iosender::ByteReceivedHandler *byteHandler) {
Comms::SetCom(this);
reply = "";
dataReceivedHandler = dataHandler;
byteReceivedHandler = byteHandler;
if (!string_contains(host, ":")) {
host += ":23";
}
auto parameter = split_string(host, ":");
auto ip = parameter[0];
auto port = std::stoi(parameter[1]);
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1) {
std::cerr << "Error creating socket" << std::endl;
}
struct sockaddr_in serv_addr{};
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
if (inet_pton(AF_INET, ip.c_str(), &serv_addr.sin_addr) <= 0) {
std::cerr << "Invalid address/ Address not supported" << std::endl;
return;
}
auto status = connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (status < 0) {
std::cerr << "Connection failed";
return;
}
isConnected = true;
// set non-blocking please, after we connected
fcntl(fd, F_SETFL, O_NONBLOCK);
workerThread = std::thread(&iosender::TelnetStream::readWorker, this);
}
iosender::TelnetStream::~TelnetStream() {
Close();
}
void iosender::TelnetStream::readWorker() {
std::string received;
uint8_t buffer[200];
while (!shouldQuit) {
if (isConnected) {
// anything to read?
auto readBytes = read(fd, buffer, 200);
if (readBytes == -1 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
// do nothing
} else if (readBytes == -1) {
std::cerr << "Failed while reading." << std::endl;
Close();
} else {
for (int i = 0; i < readBytes; i++) {
auto isEol = buffer[i] == '\n';
if (isEol) {
reply = received;
CommandState = reply == "ok" ?
Comms::State::ACK :
(starts_with(reply, "error") ?
Comms::State::NAK :
Comms::State::DataReceived);
if (!reply.empty() && dataReceivedHandler != nullptr) {
dataReceivedHandler->DataReceived(reply);
}
received.clear();
} else {
received.push_back(static_cast<char>(buffer[i]));
}
}
}
// give some time to others
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
}