26 #include <boost/archive/binary_iarchive.hpp>
27 #include <boost/archive/binary_oarchive.hpp>
28 #include <boost/property_tree/ptree_serialization.hpp>
29 #include <netinet/in.h>
34 const boost::property_tree::ptree &cfg,
38 , server_(ctx,
zmqpp::socket_type::stream)
39 , bus_sub_(ctx,
zmqpp::socket_type::sub)
40 , core_(ctx,
zmqpp::socket_type::req)
44 core_.connect(
"inproc://leosac-kernel");
46 bus_sub_.connect(
"inproc://zmq-bus-pub");
58 boost::property_tree::ptree module_config =
config_.get_child(
"module_config");
60 uint16_t port = module_config.get<uint16_t>(
"port", 4242);
61 std::string reader_name = module_config.get_child(
"reader").data();
62 stream_mode_ = module_config.get<
bool>(
"stream_mode",
true);
64 INFO(
"Rpleth module will bind to "
65 << port <<
" and will control the device nammed " << reader_name
67 reader_ = std::unique_ptr<Hardware::FWiegandReader>(
69 server_.bind(
"tcp://*:" + std::to_string(port));
79 msg >> identity >> content;
81 if (content.size() == 0)
87 INFO(
"client disconnected");
96 INFO(
"Client connected");
104 clients_[identity].write(
reinterpret_cast<const uint8_t *
>(content.c_str()),
117 std::array<uint8_t, buffer_size> buffer;
122 if (response.
command == RplethProtocol::HIDCommands::Greenled ||
123 response.
command == RplethProtocol::HIDCommands::Beep)
129 msg << client_identity;
130 msg.add_raw(&buffer[0], size);
151 else if (response.
type == RplethProtocol::TypeCode::HID &&
152 response.
command == RplethProtocol::HIDCommands::Greenled)
154 else if (response.
type == RplethProtocol::TypeCode::HID &&
155 response.
command == RplethProtocol::HIDCommands::Beep)
157 else if (response.
type == RplethProtocol::TypeCode::HID &&
158 response.
command == RplethProtocol::HIDCommands::SendCards)
160 else if (response.
type == RplethProtocol::TypeCode::HID &&
161 response.
command == RplethProtocol::HIDCommands::ReceiveCardsWaited)
163 else if (response.
type == RplethProtocol::TypeCode::Rpleth &&
164 response.
command == RplethProtocol::RplethCommands::DHCPState)
166 else if (response.
type == RplethProtocol::TypeCode::Rpleth &&
167 response.
command == RplethProtocol::RplethCommands::SetDHCP)
169 else if (response.
type == RplethProtocol::TypeCode::Rpleth &&
170 response.
command == RplethProtocol::RplethCommands::SetIP)
172 else if (response.
type == RplethProtocol::TypeCode::Rpleth &&
173 response.
command == RplethProtocol::RplethCommands::SetSubnet)
175 else if (response.
type == RplethProtocol::TypeCode::Rpleth &&
176 response.
command == RplethProtocol::RplethCommands::SetGateway)
178 else if (response.
type == RplethProtocol::TypeCode::Rpleth &&
179 response.
command == RplethProtocol::RplethCommands::Reset)
183 WARN(
"Unhandled packet.");
188 catch (std::exception &e)
190 ERROR(
"Exception while handling rpleth packet: " << e.what());
207 msg >> card_id >> nb_bit_read;
209 DEBUG(
"Rpleth module registered card with id "
210 << card_id <<
" and " << nb_bit_read <<
" significants bits");
215 card_id.erase(std::remove(card_id.begin(), card_id.end(),
':'), card_id.end());
227 auto itr_start = packet.
data.begin();
228 std::vector<Byte>::const_iterator my_start = itr_start;
229 std::vector<Byte>::const_iterator it;
231 WARN(
"Should not be here");
235 while (my_start != packet.
data.end())
237 it = std::find(itr_start, packet.
data.end(),
'|');
239 while (my_start != packet.
data.end() && my_start != it)
245 if (my_start == packet.
data.end())
256 std::list<std::string> to_send;
258 WARN(
"Should not be here");
259 DEBUG(
"Packet size = " << packet.
data.size());
260 if (packet.
data.size() != 1)
262 WARN(
"Invalid Packet");
265 if (packet.
data[0] == 0x01)
267 DEBUG(
"Present list");
273 DEBUG(
"Absent list");
276 auto lambda = [
this](
const std::string &str) ->
bool {
283 to_send.erase(std::remove_if(to_send.begin(), to_send.end(), lambda),
288 std::vector<Byte> data;
289 data.reserve(to_send.size() * 8);
290 for (
auto &card : to_send)
293 card.erase(std::remove(card.begin(), card.end(),
':'), card.end());
294 data.insert(data.end(), card.begin(), card.end());
297 response.
data = data;
298 response.
dataLen = data.size();
304 if (packet.
data.size() > 0)
306 if (packet.
data[0] == 0x01)
308 else if (packet.
data[0] == 0x00)
311 WARN(
"Malformed (Rpleth Beep) packet. Data byte is invalid");
314 WARN(
"Malformed (Rpleth Beep) packet. Not enough data");
319 if (packet.
data.size() > 0)
321 if (packet.
data[0] == 0x01)
323 else if (packet.
data[0] == 0x00)
326 WARN(
"Malformed (Rpleth GreenLed) packet. Data byte is invalid");
329 WARN(
"Malformed (Rpleth GreenLed) packet. Not enough data");
359 std::array<uint8_t, 64> buf;
362 msg.add_raw(&buf, size);
370 static uint64_t htonll(uint64_t value)
373 if (*(
char *)&num == 42)
375 uint32_t high_part = htonl((uint32_t)(value >> 32));
376 uint32_t low_part = htonl((uint32_t)(value & 0xFFFFFFFFLL));
377 return (((uint64_t)low_part) << 32) | high_part;
391 std::vector<uint8_t> ret;
397 ret.resize(
sizeof(num));
398 std::memcpy(&ret[0], &num,
sizeof(num));
407 response.
type = RplethProtocol::TypeCode::Rpleth;
408 response.
command = RplethProtocol::RplethCommands::DHCPState;
411 if (network_cfg.get<
bool>(
"enabled"))
414 response.
data = network_cfg.get<
bool>(
"dhcp")
415 ? std::vector<uint8_t>({1})
416 : std::vector<uint8_t>({0});
424 catch (
const std::exception &e)
426 ERROR(
"Exception while getting DHCP state: " << e.what());
437 response.
type = RplethProtocol::TypeCode::Rpleth;
438 response.
command = RplethProtocol::RplethCommands::SetDHCP;
441 ERROR(
"Invalid Rpleth Packet");
442 else if (network_cfg.get<
bool>(
"enabled"))
444 network_cfg.erase(
"dhcp");
445 network_cfg.put(
"dhcp", p.
data[0] ?
true :
false);
449 WARN(
"Failed to update network config.");
452 INFO(
"Network not managed by Leosac, doing nothing.");
462 response.
type = RplethProtocol::TypeCode::Rpleth;
463 response.
command = RplethProtocol::RplethCommands::SetIP;
466 ERROR(
"Invalid Rpleth Packet");
467 else if (network_cfg.get<
bool>(
"enabled"))
469 std::ostringstream oss;
470 for (
unsigned char i = 0; i < 4; ++i)
472 oss << std::to_string(p.
data[i]);
476 INFO(
"new ip = {" << oss.str() <<
"}");
477 network_cfg.erase(
"default_ip");
478 network_cfg.put(
"default_ip", oss.str());
482 WARN(
"Failed to update network config.");
485 INFO(
"Network not managed by Leosac, doing nothing.");
495 response.
type = RplethProtocol::TypeCode::Rpleth;
496 response.
command = RplethProtocol::RplethCommands::SetSubnet;
499 ERROR(
"Invalid Rpleth Packet");
500 else if (network_cfg.get<
bool>(
"enabled"))
502 std::ostringstream oss;
503 for (
unsigned char i = 0; i < 4; ++i)
505 oss << std::to_string(p.
data[i]);
509 network_cfg.erase(
"netmask");
510 network_cfg.put(
"netmask", oss.str());
514 WARN(
"Failed to update network config.");
517 INFO(
"Network not managed by Leosac, doing nothing.");
527 response.
type = RplethProtocol::TypeCode::Rpleth;
528 response.
command = RplethProtocol::RplethCommands::SetGateway;
531 ERROR(
"Invalid Rpleth Packet");
532 else if (network_cfg.get<
bool>(
"enabled"))
534 std::ostringstream oss;
535 for (
unsigned char i = 0; i < 4; ++i)
537 oss << std::to_string(p.
data[i]);
541 network_cfg.erase(
"gateway");
542 network_cfg.put(
"gateway", oss.str());
546 WARN(
"Failed to update network config.");
549 INFO(
"Network not managed by Leosac, doing nothing.");
555 std::ostringstream oss;
556 boost::archive::binary_oarchive archive(oss);
557 boost::property_tree::save(archive, tree, 1);
558 core_.send(zmqpp::message() <<
"SET_NETCONFIG" << oss.str());
562 return ret ==
"OK" ? true :
false;
567 boost::property_tree::ptree network_config;
570 core_.send(
"GET_NETCONFIG");
572 zmqpp::message response;
573 core_.receive(response);
574 assert(response.parts() == 1);
577 std::istringstream iss(data);
578 boost::archive::binary_iarchive archive(iss);
579 boost::property_tree::load(archive, network_config, 1);
581 return network_config;
587 core_.send(
"RESTART");