-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheISCP.cpp
112 lines (90 loc) · 2.39 KB
/
eISCP.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "Arduino.h"
#include "eISCP.h"
void eISCP_Message::decode(char* cmsg) {
// Strip terminating characters
String msg = String(strtok(cmsg, "\x1A\0\r\n"));
// Check if we have a valid eISCP message
if(msg.substring(0, 2) == "!1")
valid = true;
else
valid = false;
content = msg.substring(2);
}
String eISCP_Message::encode() {
// Add prefix and a terminating character
return "!1" + content + '\r';
}
eISCP_Message::eISCP_Message(String _content){
content = _content;
valid = false;
}
eISCP::eISCP(const char _ip_address[], int _port, Client* _client) {
ip_address = _ip_address;
port = _port;
client = _client;
callback = nullptr;
}
void eISCP::set_callback(void (*_callback)(eISCP_Message)) {
callback = _callback;
}
bool eISCP::connected() {
if(!client->connected() && !client->available())
if (!client->connect(ip_address, port))
return false;
return true;
}
void eISCP::handle() {
if(!connected()) return;
// Read all incoming messages
while(client->available() >= 16){
yield();
get_packet();
}
}
bool eISCP::send(String command) {
eISCP_Message message(command);
return send_packet(&message);
}
bool eISCP::send_packet(eISCP_Message* message) {
if(!connected()){
return false;
}
eISCP_Header header;
header.size_body = __builtin_bswap32(message->encode().length());
const byte* p = (const byte*) &header;
for (unsigned int i = 0; i < sizeof header; i++)
client->write(*p++);
client->print(message->encode());
return true;
}
void eISCP::get_packet() {
if(!connected()) return;
eISCP_Header header;
if(client->readBytes((byte*) &header, 16) == 16){
// Swap endianness
header.size_header = __builtin_bswap32(header.size_header);
header.size_body = __builtin_bswap32(header.size_body);
// Check if header is valid
if(strncmp(header.magic, "ISCP", 4) != 0 || header.size_header != 16)
return;
} else return;
char* buffer = new char[header.size_body];
unsigned long timeout = millis(), index = 0;
// Read message to buffer byte by byte
while(index < header.size_body){
yield();
if (millis() - timeout > eISCP_REQUEST_TIMEOUT)
break;
byte b = client->read();
if(b) buffer[index++] = b;
}
eISCP_Message message;
message.decode(buffer);
delete[] buffer;
// Check if the whole message was read
if(index != header.size_body)
message.valid = false;
// Call the callback function if present
if(callback != nullptr)
callback(message);
}