-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSWGPacket.cpp
More file actions
148 lines (138 loc) · 3.72 KB
/
SWGPacket.cpp
File metadata and controls
148 lines (138 loc) · 3.72 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
/*
* SWGPacket.cpp
*
* Created on: Jul 30, 2021
* Author: dmounday
*/
#include "SWGPacket.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
namespace pt=boost::property_tree;
namespace pentair_control {
SWGPacket::SWGPacket ():
swgState_ {SWGState::SWG_UNDEFINED}
{
}
SWGPacket::~SWGPacket () {}
PacketState
SWGPacket::CapturePacket(uint8_t b){
switch ( swgState_ ){
case SWGState::SWG_UNDEFINED:
data_.clear();
if ( b == DLE ){
swgState_ = SWGState::SWG_STX;
} else {
++badData_;
return PacketState::UNDEFINED;
}
break;
case SWGState::SWG_STX:
if ( b == STX ){
swgState_ = SWGState::SWG_DEST;
} else {
++badData_;
swgState_= SWGState::SWG_UNDEFINED;
return PacketState::UNDEFINED;
}
break;
case SWGState::SWG_DEST:
data_.push_back(b);
swgState_ = SWGState::SWG_MSGID;
break;
case SWGState::SWG_MSGID:
data_.push_back( b );
swgState_ = SWGState::SWG_DATA;
// now accumulate data until DLE ETX character sequence.
break;
case SWGState::SWG_DATA:
data_.push_back(b);
if ( b == DLE ) // check for DLE
swgState_ = SWGState::SWG_DATA_DLE; // may be data or start of DLE ETX
// else stay in data state
if ( data_.size() > SWG_DATA_LTH){
++badData_;
swgState_ = SWGState::SWG_UNDEFINED;
return PacketState::UNDEFINED;
}
break;
case SWGState::SWG_DATA_DLE:
if ( b == ETX ) { // end of packet
data_.pop_back(); // pop DLE
uint8_t cksum = data_.back();
data_.pop_back(); // remove ckeck sum
uint8_t calc_ck_sum =DLE + STX; // check sum includes leading DLE/STX.
for ( uint8_t x: data_) {
calc_ck_sum += x;
}
if ( cksum == calc_ck_sum ){
swgState_ = SWGState::SWG_UNDEFINED; // reset state for next msg.
++totalPackets_;
return PacketState::SWG_COMPLETE; // return complete SWG packet.
} else {
swgState_ = SWGState::SWG_UNDEFINED;
++ckSumErrors_;
return PacketState::UNDEFINED;
}
} else {
// just more data so go back to SWG_DATA state;
data_.push_back(b);
swgState_ = SWGState::SWG_DATA;
}
break;
default:
PLOG(plog::error)<< "SWG Packet state error";
++badData_;
swgState_ = SWGState::SWG_UNDEFINED;
return PacketState::UNDEFINED;
break;
}
return PacketState::SWG_INCOMPLETE;
}
std::string SWGPacket::ByteToHex(uint8_t b)
{
std::stringstream ss;
ss << "0x" << std::setfill('0') << std::setw(2)
<< std::hex << static_cast<int>(b);
return ss.str();
}
std::string SWGPacket::PacketJSON()
{
std::stringstream ss;
pt::ptree tree;
if (MsgID() == INFO_RESP)
{
pt::ptree info;
info.add("SaltPPM", data_[2]);
std::string model;
for (auto i = 3; i < data_.size(); ++i)
model += data_[i];
info.add("model", model);
tree.push_back(std::make_pair("IC40Info", info));
}
else if (MsgID() == GET_SANITIZER_RESP)
{
pt::ptree resp;
resp.add("Temperture", data_[2]);
resp.add("percent", data_[3]);
resp.add("byte6", ByteToHex(data_[4]));
resp.add("byte7", ByteToHex(data_[5]));
tree.push_back(std::make_pair("Sanitizer", resp));
}
else if (MsgID() == SET_SANITIZER_RESP)
{
pt::ptree resp;
resp.add("salinity", data_[2]);
resp.add("status", ByteToHex(data_[3]));
resp.add("flow", data_[3] & 0x01 ? "No Flow" : "Flow OK");
tree.push_back(std::make_pair("Sanitizer", resp));
}
else if (MsgID() == STATUS_RESP)
{
pt::ptree resp;
resp.add("Status", ByteToHex(data_[2]));
tree.push_back(std::make_pair("IC40.status", resp));
}
pt::write_json(ss, tree);
return ss.str();
}
} /* namespace pentair_control */