-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEtherEvent.cpp
More file actions
208 lines (173 loc) · 9.65 KB
/
EtherEvent.cpp
File metadata and controls
208 lines (173 loc) · 9.65 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// EtherEvent - Easy to use password authenticated network communication between Arduinos and EventGhost Network Event Sender/Receiver and TCPEvents plugins: http://github.com/per1234/EtherEvent
#define ETHEREVENT_NO_AUTHENTICATION //this is to prevent EtherEvent.cpp's include of EtherEvent.h from including MD5.h(not needed in this file even with authentication enabled
#include "EtherEvent.h"
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//constructor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
EtherEventClass::EtherEventClass() {
timeout = timeoutDefault; //set default timeout value, this can be changed by the user via setTimeout()
sendDoubleDecimalPlaces = sendDoubleDecimalPlacesDefault;
noPayload = false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//begin
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
boolean EtherEventClass::begin(const byte eventLengthMaxInput, const unsigned int payloadLengthMaxInput) {
#if ETHEREVENT_DEBUG == true
delay(20); //There needs to be a delay between the calls to serial.begin() in the sketch setup() and here or garbage will be printed to the serial monitor
#endif
ETHEREVENT_SERIAL.begin(EtherEventNamespace::debugSerialBaud); //for debugging
ETHEREVENT_SERIAL.println(F("\n\n\nEtherEvent.begin"));
eventLengthMax = eventLengthMaxInput;
payloadLengthMax = payloadLengthMaxInput;
availableEventSubmessageLengthMax = max(max(EtherEventNamespace::payloadWithoutReleaseLength, EtherEventNamespace::payloadSeparatorLength + payloadLengthMax + TCPEventsPayloadFormattingLength), eventLengthMax);
if (availableEventSubmessageLengthMax > availableEventSubmessageLengthMax + 1) { //availableEventSubmessageLengthMax is the max value of the type
availableEventSubmessageLengthMax--; //have to decrement because I need to add one in the event/payload handler section of availableEvent()
}
receivedEvent = (char*)realloc(receivedEvent, (eventLengthMax + 1) * sizeof(*receivedEvent));
flushEvent(); //clear buffer - realloc does not zero initialize so the buffer could contain anything
receivedPayload = (char*)realloc(receivedPayload, (payloadLengthMax + 1) * sizeof(*receivedPayload));
flushPayload(); //clear buffer - realloc does not zero initialize so the buffer could contain anything
if (receivedEvent == NULL || receivedPayload == NULL) {
ETHEREVENT_SERIAL.println(F("memory allocation failed"));
return false;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//availablePayload - returns the number of chars in the payload including the null terminator if there is one
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int EtherEventClass::availablePayload() {
if (receivedPayloadLength > readPayloadLength) {
return receivedPayloadLength - readPayloadLength;
}
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//readEvent
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EtherEventClass::readEvent(char eventBuffer[]) {
for (byte charCounter = readEventLength; charCounter < receivedEventLength; charCounter++) {
eventBuffer[charCounter - readEventLength] = receivedEvent[charCounter];
}
flushEvent();
}
char EtherEventClass::readEvent() {
if (receivedEventLength > readEventLength + 1) {
return receivedEvent[readEventLength++];
}
flushEvent();
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//readPayload
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EtherEventClass::readPayload(char payloadBuffer[]) {
for (unsigned int charCounter = readPayloadLength; charCounter < receivedPayloadLength; charCounter++) {
payloadBuffer[charCounter - readPayloadLength] = receivedPayload[charCounter];
}
flushPayload();
}
char EtherEventClass::readPayload() {
if (receivedPayloadLength > readPayloadLength + 1) {
return receivedPayload[readPayloadLength++];
}
flushPayload();
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//flushReceiver - dump the last message received so another one can be received
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EtherEventClass::flushReceiver() {
ETHEREVENT_SERIAL.println(F("EtherEvent.flushReceiver: start"));
flushEvent();
flushPayload();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//senderIP - returns the ip address the current event was sent from. Requires modified ethernet library, thus the preprocesser direcive system
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef ethernetclientwithremoteIP_h //the include guard from the modified EthernetClient.h
IPAddress EtherEventClass::senderIP() {
return fromIP;
}
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//setTimeout
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EtherEventClass::setTimeout(const unsigned int timeoutInput) {
timeout = timeoutInput;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//getTimeout
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int EtherEventClass::getTimeout() {
return timeout;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//setPassword
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
boolean EtherEventClass::setPassword(const char passwordInput[]) {
ETHEREVENT_SERIAL.println(F("EtherEvent.setPassword(char)"));
passwordLength = strlen(passwordInput);
password = (char*)realloc(password, (passwordLength + 1) * sizeof(*password)); //allocate memory for the password
strcpy(password, passwordInput); //store the password
if (password == NULL) {
ETHEREVENT_SERIAL.println(F("EtherEvent.setPassword: memory allocation failed"));
return false;
}
return true;
}
boolean EtherEventClass::setPassword(const __FlashStringHelper* passwordInput) {
ETHEREVENT_SERIAL.println(F("EtherEvent.setPassword(F())"));
passwordLength = FSHlength(passwordInput);
password = (char*)realloc(password, (passwordLength + 1) * sizeof(*password)); //allocate memory for the password
if (password == NULL) {
ETHEREVENT_SERIAL.println(F("EtherEvent.setPassword: memory allocation failed"));
return false;
}
memcpy_P(password, passwordInput, passwordLength + 1); //+1 for the null terminator
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//IPtoa - convert IPAddress to char array and put it in the passed buffer
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EtherEventClass::IPtoa(const IPAddress &IP, char IPcharBuffer[]) {
utoa(IP[0], IPcharBuffer, 10); //convert the first octet
for (byte octetCount = 1; octetCount < 4; octetCount++) { //convert the other 3 octets
strcat(IPcharBuffer, ".");
char octetChar[3 + 1]; //3 digit byte + null terminator
utoa(IP[octetCount], octetChar, 10); //convert the first octet
strcat(IPcharBuffer, octetChar);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FSHlength - determine length of __FlashStringHelper
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int EtherEventClass::FSHlength(const __FlashStringHelper* FSHinput) {
const char* FSHinputPointer = (const char PROGMEM *)FSHinput;
unsigned int stringLength = 0;
while (pgm_read_byte(FSHinputPointer++)) {
stringLength++;
}
return stringLength;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//private
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//flushEvent
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EtherEventClass::flushEvent() {
receivedEvent[0] = 0; //reset the event buffer
receivedEventLength = 0;
readEventLength = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//flushPayload
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EtherEventClass::flushPayload() {
receivedPayload[0] = 0; //reset the event buffer
receivedPayloadLength = 0;
readPayloadLength = 0;
}
EtherEventClass EtherEvent; //This sets up a single global instance of the library so the class doesn't need to be declared in the user sketch and multiple instances are not necessary in this case.