22#include "protobuf_adapter.h"
26#include <utils/misc/string_split.h>
28#include <AdapterConfiguration.hh>
29#include <AdapterExecInterface.hh>
30#include <AdapterFactory.hh>
32#include <InterfaceManager.hh>
33#include <StateCacheEntry.hh>
38using namespace protobuf_comm;
39using namespace google::protobuf;
40using namespace boost::placeholders;
51: InterfaceAdapter(execInterface)
61 pugi::xml_node
const xml)
62: InterfaceAdapter(execInterface, xml)
77 logger_ =
reinterpret_cast<fawkes::Logger *
>(m_execInterface.getProperty(
"::Fawkes::Logger"));
80 clock_ =
reinterpret_cast<fawkes::Clock *
>(m_execInterface.getProperty(
"::Fawkes::Clock"));
82 std::string cfg_proto_dir = get_xml_config_value(getXml(),
"protos");
83 replace_tokens(cfg_proto_dir);
85 std::vector<std::string> cfg_proto_dirs{cfg_proto_dir};
86 logger_->
log_info(
"PlexilProtobuf",
"Protobuf message spec dir: %s", cfg_proto_dirs[0].c_str());
91 message_register_ = std::make_shared<MessageRegister>(cfg_proto_dirs);
93 namespace p = std::placeholders;
95 {
"ReceiveCommand", std::bind(&ProtobufCommPlexilAdapter::proc_receive_command,
this, p::_1)},
96 {
"GetParameter", std::bind(&ProtobufCommPlexilAdapter::proc_get_param_command,
this, p::_1)},
97 {
"SendReturnValue", std::bind(&ProtobufCommPlexilAdapter::proc_send_rv_command,
this, p::_1)},
98 {
"pb_create", std::bind(&ProtobufCommPlexilAdapter::pb_create,
this, p::_1)},
99 {
"pb_destroy", std::bind(&ProtobufCommPlexilAdapter::pb_destroy,
this, p::_1)},
100 {
"pb_set_value", std::bind(&ProtobufCommPlexilAdapter::pb_set_value,
this, p::_1)},
102 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::INTEGER_TYPE)},
104 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::REAL_TYPE)},
106 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::BOOLEAN_TYPE)},
108 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::STRING_TYPE)},
109 {
"pb_get_length", std::bind(&ProtobufCommPlexilAdapter::pb_get_length,
this, p::_1)},
110 {
"pb_has_field", std::bind(&ProtobufCommPlexilAdapter::pb_has_field,
this, p::_1)},
111 {
"pb_broadcast", std::bind(&ProtobufCommPlexilAdapter::pb_broadcast,
this, p::_1)},
112 {
"pb_tostring", std::bind(&ProtobufCommPlexilAdapter::pb_tostring,
this, p::_1)},
113 {
"pb_peer_create", std::bind(&ProtobufCommPlexilAdapter::pb_peer_create,
this, p::_1)},
114 {
"pb_peer_destroy", std::bind(&ProtobufCommPlexilAdapter::pb_get_length,
this, p::_1)},
115 {
"pb_peer_create_local",
116 std::bind(&ProtobufCommPlexilAdapter::pb_peer_create_local,
this, p::_1)},
117 {
"pb_peer_create_crypto",
118 std::bind(&ProtobufCommPlexilAdapter::pb_peer_create_crypto,
this, p::_1)},
119 {
"pb_peer_create_local_crypto",
120 std::bind(&ProtobufCommPlexilAdapter::pb_peer_create_local_crypto,
this, p::_1,
nullptr)},
121 {
"pb_peer_setup_crypto",
122 std::bind(&ProtobufCommPlexilAdapter::pb_peer_setup_crypto,
this, p::_1)},
125 for (
const auto &c : commands_) {
126 PLEXIL::g_configuration->registerCommandInterface(c.first,
this);
147 std::lock_guard<std::mutex> lock(queue_mutex_);
178 std::string
const &name = cmd->getName();
182 auto c = commands_.find(name);
183 if (c != commands_.end()) {
186 warn(
"ProtobufCommAdapter:executeCommand: called for unknown"
189 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
190 m_execInterface.notifyOfExternalEvent();
195ProtobufCommPlexilAdapter::proc_receive_command(PLEXIL::Command *cmd)
197 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
198 if (args.size() != 1) {
199 warn(
"ProtobufCommAdapter: The ReceiveCommand"
200 " command requires exactly one argument");
201 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
202 m_execInterface.notifyOfExternalEvent();
206 if (args.front().valueType() != PLEXIL::STRING_TYPE) {
207 warn(
"ProtobufCommAdapter: The argument to the ReceiveCommand"
209 << args.front() <<
", is not a string");
210 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
211 m_execInterface.notifyOfExternalEvent();
215 std::string msg_type;
216 if (!args.front().getValue(msg_type)) {
217 warn(
"ProtobufCommAdapter: message type is unknown");
218 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
219 m_execInterface.notifyOfExternalEvent();
223 add_recipient(msg_type, cmd);
224 proc_queue(msg_type);
226 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SENT_TO_SYSTEM);
227 m_execInterface.notifyOfExternalEvent();
231ProtobufCommPlexilAdapter::proc_get_param_command(PLEXIL::Command *cmd)
233 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
234 if (args.size() < 1 || args.size() > 2) {
235 warn(
"ProtobufCommAdapter:GetParameter: "
236 "Command requires either one or two arguments");
237 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
238 m_execInterface.notifyOfExternalEvent();
242 if (args.front().valueType() != PLEXIL::STRING_TYPE) {
243 warn(
"ProtobufCommAdapter:GetParameter: first argument "
245 << args.front() <<
"' is not a string");
246 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
247 m_execInterface.notifyOfExternalEvent();
252 if (!args.front().getValue(msg_id)) {
253 warn(
"ProtobufCommAdapter:GetParameter: message ID is unknown");
254 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
255 m_execInterface.notifyOfExternalEvent();
259 std::lock_guard<std::mutex> lock(queue_mutex_);
261 if (messages_.find(msg_id) == messages_.end()) {
262 warn(
"ProtobufCommAdapter:GetParameter: message ID not in queued messages");
263 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
264 m_execInterface.notifyOfExternalEvent();
268 std::vector<PLEXIL::Value>::const_iterator it = ++args.begin();
270 if (it != args.end()) {
271 if (it->valueType() != PLEXIL::INTEGER_TYPE) {
272 warn(
"ProtobufCommAdapter:GetParameter: second argument "
274 << *it <<
"' is not an integer");
275 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
276 m_execInterface.notifyOfExternalEvent();
280 if (!it->getValue(
id)) {
281 warn(
"ProtobufCommAdapter:GetParameter: second argument is unknown");
282 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
283 m_execInterface.notifyOfExternalEvent();
287 if (id < 0 || id > 3) {
288 warn(
"ProtobufCommAdapter:GetParameter: second argument "
290 << *it <<
"' is not a valid index (must be 0..3)");
291 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
292 m_execInterface.notifyOfExternalEvent();
297 const message_meta &msgmeta = messages_[msg_id];
300 case 0: m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msg_id));
break;
301 case 1: m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msgmeta.from_host));
break;
302 case 2: m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msgmeta.from_port));
break;
304 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msgmeta.time_received.in_sec()));
308 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
309 m_execInterface.notifyOfExternalEvent();
313ProtobufCommPlexilAdapter::proc_send_rv_command(PLEXIL::Command *cmd)
315 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
316 if (args.size() == 0) {
317 warn(
"ProtobufCommAdapter:SendReturnValue: The SendReturnValue"
318 " command requires at least one argument");
319 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
320 m_execInterface.notifyOfExternalEvent();
324 if (args.front().valueType() != PLEXIL::STRING_TYPE) {
325 warn(
"ProtobufCommAdapter:SendReturnValue: The argument to the "
326 "SendReturnValue command, "
327 << args.front() <<
", is not a string");
328 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
329 m_execInterface.notifyOfExternalEvent();
334 if (!args.front().getValue(msg_id)) {
335 warn(
"ProtobufCommAdapter:SendReturnValue: message ID is unknown");
336 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
337 m_execInterface.notifyOfExternalEvent();
341 release_message(msg_id);
343 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
344 m_execInterface.notifyOfExternalEvent();
353 m_execInterface.handleCommandAbortAck(cmd,
false);
354 m_execInterface.notifyOfExternalEvent();
358ProtobufCommPlexilAdapter::add_recipient(
const std::string &msg_type, PLEXIL::Command *cmd)
360 std::lock_guard<std::mutex> lock(queue_mutex_);
361 queue_entry & q = get_queue(msg_type);
362 q.recipients.push_back(cmd);
366ProtobufCommPlexilAdapter::remove_recipient(
const std::string &msg_type, PLEXIL::Command *cmd)
368 std::lock_guard<std::mutex> lock(queue_mutex_);
369 queue_entry & q = get_queue(msg_type);
370 q.recipients.erase(std::remove(q.recipients.begin(), q.recipients.end(), cmd),
375ProtobufCommPlexilAdapter::add_message(
const std::string &msg_type, message_meta &&msg)
377 std::lock_guard<std::mutex> lock(queue_mutex_);
378 queue_entry & q = get_queue(msg_type);
379 std::string msg_id = gen_msgid(msg_type);
381 messages_[msg_id] = std::move(msg);
383 q.messages.push_back(msg_id);
387ProtobufCommPlexilAdapter::release_message(
const std::string &msg_id)
389 std::lock_guard<std::mutex> lock(queue_mutex_);
391 std::string::size_type colon_pos = msg_id.find(
':');
392 if (colon_pos != std::string::npos) {
393 std::string msg_type{msg_id.substr(0, colon_pos)};
394 queue_entry &q = get_queue(msg_type);
396 q.messages.erase(std::remove(q.messages.begin(), q.messages.end(), msg_id), q.messages.end());
397 messages_.erase(msg_id);
401std::shared_ptr<google::protobuf::Message>
402ProtobufCommPlexilAdapter::get_message(
const std::string &msg_id)
404 std::shared_ptr<google::protobuf::Message> m;
406 std::lock_guard<std::mutex> lock(queue_mutex_);
408 if (messages_.find(msg_id) != messages_.end()) {
409 m = messages_[msg_id].message;
415ProtobufCommPlexilAdapter::gen_msgid(
const std::string &msg_type)
417 unsigned long int id = ++msg_counter_;
418 return msg_type +
":" + std::to_string(
id);
422ProtobufCommPlexilAdapter::proc_queue(
const std::string &msg_type)
424 std::lock_guard<std::mutex> lock(queue_mutex_);
425 queue_entry & q = get_queue(msg_type);
426 auto mi = q.messages.begin();
427 auto ri = q.recipients.begin();
428 bool notify = !q.messages.empty() && !q.recipients.empty();
429 while (mi != q.messages.end() && ri != q.recipients.end()) {
430 m_execInterface.handleCommandReturn(*ri, *mi);
431 ri = q.recipients.erase(ri);
432 mi = q.messages.erase(mi);
435 m_execInterface.notifyOfExternalEvent();
439ProtobufCommPlexilAdapter::queue_entry &
440ProtobufCommPlexilAdapter::get_queue(
const std::string &msg_type)
442 auto q = queue_.find(msg_type);
443 if (q != queue_.end()) {
446 auto new_q = queue_.insert(std::make_pair(msg_type, queue_entry()));
447 return new_q.first->second;
454ProtobufCommPlexilAdapter::pb_create(PLEXIL::Command *cmd)
456 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
457 if (!verify_args(args,
"ProtobufCommAdapter:pb_create", {{
"msg_type", PLEXIL::STRING_TYPE}})) {
458 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
459 m_execInterface.notifyOfExternalEvent();
463 std::string msg_type;
464 args[0].getValue(msg_type);
466 std::lock_guard<std::mutex> lock(queue_mutex_);
467 std::string msg_id = gen_msgid(msg_type);
470 std::shared_ptr<google::protobuf::Message> m = message_register_->new_message_for(msg_type);
472 message_meta msgmeta{.time_received =
fawkes::Time(clock_),
475 .message = std::shared_ptr<google::protobuf::Message>(m)};
477 messages_[msg_id] = std::move(msgmeta);
479 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msg_id));
480 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
481 m_execInterface.notifyOfExternalEvent();
482 }
catch (std::runtime_error &e) {
484 "Cannot create message of type %s: %s",
487 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
488 m_execInterface.notifyOfExternalEvent();
495ProtobufCommPlexilAdapter::pb_destroy(PLEXIL::Command *cmd)
497 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
498 if (!verify_args(args,
"ProtobufCommAdapter:pb_destroy", {{
"msg_id", PLEXIL::STRING_TYPE}})) {
499 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
500 m_execInterface.notifyOfExternalEvent();
505 args[0].getValue(msg_id);
507 std::lock_guard<std::mutex> lock(queue_mutex_);
508 messages_.erase(msg_id);
511static std::pair<std::string, long int>
512parse_field_name(
const std::string &field_name,
const std::string &func)
517 std::string::size_type opening = field_name.find(
'[');
518 if (opening != std::string::npos) {
519 std::string::size_type closing = field_name.find(
']', opening);
520 if (closing != std::string::npos) {
521 field = field_name.substr(0, opening);
522 std::string idx_str = field_name.substr(opening + 1, closing - opening - 1);
523 if (idx_str.empty()) {
524 index = std::numeric_limits<long int>::max();
526 index = std::stol(idx_str);
529 warn(
"ProtobufCommAdapter:" << func <<
":"
530 <<
" Missing closing bracket in " << field_name);
535 return std::make_pair(field, index);
539traverse_field(google::protobuf::Message *&msg,
540 const std::string & field_name,
541 const FieldDescriptor *& field,
542 std::string & partial_name,
543 long int & partial_index,
544 const std::string & func)
547 std::vector<std::string> field_path = str_split(field_name,
'.');
548 for (
size_t i = 0; i < field_path.size(); ++i) {
549 std::pair<std::string, long int> parsed_field = parse_field_name(field_path[i], func);
550 partial_name = parsed_field.first;
551 partial_index = parsed_field.second;
553 if (partial_name.empty()) {
554 warn(
"ProtobufCommAdapter:" << func <<
":"
555 <<
" Invalid sub-field " << field_path[i]);
559 const Descriptor *desc = msg->GetDescriptor();
560 field = desc->FindFieldByName(partial_name);
562 warn(
"ProtobufCommAdapter:" << func <<
":"
563 <<
" Field " << partial_name <<
" not found");
567 if (partial_index >= 0 && !field->is_repeated()) {
568 warn(
"ProtobufCommAdapter:" << func <<
":"
569 <<
" Index for non-repeated field " << partial_name);
572 }
else if (partial_index < 0 && field->is_repeated()) {
573 warn(
"ProtobufCommAdapter:" << func <<
":"
574 <<
" No index for repeated field " << partial_name);
578 const Reflection *refl = msg->GetReflection();
584 if (field->is_repeated() && partial_index >= 0
585 && partial_index == refl->FieldSize(*msg, field)) {
586 partial_index = std::numeric_limits<long int>::max();
589 if (partial_index >= 0 && partial_index < std::numeric_limits<long int>::max()
590 && partial_index >= refl->FieldSize(*msg, field)) {
591 warn(
"ProtobufCommAdapter:" << func <<
":"
592 <<
" Index " << partial_index <<
" out of bounds for "
597 if (i < (field_path.size() - 1)) {
598 if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
599 warn(
"ProtobufCommAdapter:" << func <<
":"
600 <<
" Sub-field " << field_path[i] <<
" is not a message");
604 if (field->is_repeated()) {
605 if (partial_index == std::numeric_limits<long int>::max()) {
606 msg = refl->AddMessage(msg, field);
609 msg = refl->MutableRepeatedMessage(msg, field, partial_index);
612 msg = refl->MutableMessage(msg, field);
620ProtobufCommPlexilAdapter::pb_set_value(PLEXIL::Command *cmd)
622 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
623 if (!verify_args(args,
624 "ProtobufCommAdapter:pb_set_value",
625 {{
"msg_id", PLEXIL::STRING_TYPE},
626 {
"field", PLEXIL::STRING_TYPE},
627 {
"value", PLEXIL::UNKNOWN_TYPE}})) {
628 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
629 m_execInterface.notifyOfExternalEvent();
634 std::string field_name;
636 args[0].getValue(msg_id);
637 args[1].getValue(field_name);
640 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
642 warn(
"ProtobufCommAdapter:pb_set_value:"
643 <<
" Unknown message " << msg_id);
644 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
645 m_execInterface.notifyOfExternalEvent();
649 const FieldDescriptor * field =
nullptr;
650 google::protobuf::Message *msg = m.get();
652 std::string partial_name;
653 long int partial_index = -1;
655 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_set_value")) {
656 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
657 m_execInterface.notifyOfExternalEvent();
662 warn(
"ProtobufCommAdapter:pb_set_value:"
663 <<
" Unknown field " << field_name <<
" for message " << msg_id);
664 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
665 m_execInterface.notifyOfExternalEvent();
669 if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
670 warn(
"ProtobufCommAdapter:pb_set_value:"
671 <<
" Final sub-field " << field_name <<
" is a message");
672 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
673 m_execInterface.notifyOfExternalEvent();
677 const Reflection *refl = msg->GetReflection();
679 bool add_repeated =
false;
680 if (field->is_repeated() && partial_index == std::numeric_limits<long int>::max()) {
685 switch (field->type()) {
686 case FieldDescriptor::TYPE_DOUBLE:
687 if (value.valueType() != PLEXIL::REAL_TYPE) {
688 warn(
"ProtobufCommAdapter:pb_set_value:"
689 "Invalid type for field "
690 << field_name <<
", expects Real, got " << PLEXIL::valueTypeName(value.valueType()));
691 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
692 m_execInterface.notifyOfExternalEvent();
697 if (field->is_repeated()) {
699 refl->AddDouble(msg, field, v);
701 refl->SetRepeatedDouble(msg, field, partial_index, v);
704 refl->SetDouble(msg, field, v);
709 case FieldDescriptor::TYPE_FLOAT:
710 if (value.valueType() != PLEXIL::REAL_TYPE) {
711 warn(
"ProtobufCommAdapter:pb_set_value:"
712 "Invalid type for field "
713 << field_name <<
", expects Real, got " << PLEXIL::valueTypeName(value.valueType()));
714 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
715 m_execInterface.notifyOfExternalEvent();
720 if (field->is_repeated()) {
722 refl->AddFloat(msg, field, v);
724 refl->SetRepeatedFloat(msg, field, partial_index, v);
727 refl->SetFloat(msg, field, v);
732 case FieldDescriptor::TYPE_SFIXED64:
733 case FieldDescriptor::TYPE_SINT64:
734 case FieldDescriptor::TYPE_INT64:
735 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
736 warn(
"ProtobufCommAdapter:pb_set_value:"
737 "Invalid type for field "
738 << field_name <<
", expects Integer, got "
739 << PLEXIL::valueTypeName(value.valueType()));
740 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
741 m_execInterface.notifyOfExternalEvent();
746 refl->SetInt64(msg, field, v);
750 case FieldDescriptor::TYPE_FIXED64:
751 case FieldDescriptor::TYPE_UINT64:
752 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
753 warn(
"ProtobufCommAdapter:pb_set_value:"
754 "Invalid type for field "
755 << field_name <<
", expects Integer, got "
756 << PLEXIL::valueTypeName(value.valueType()));
757 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
758 m_execInterface.notifyOfExternalEvent();
763 if (field->is_repeated()) {
765 refl->AddUInt64(msg, field, v);
767 refl->SetRepeatedUInt64(msg, field, partial_index, v);
770 refl->SetUInt64(msg, field, v);
775 case FieldDescriptor::TYPE_SFIXED32:
776 case FieldDescriptor::TYPE_SINT32:
777 case FieldDescriptor::TYPE_INT32:
778 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
779 warn(
"ProtobufCommAdapter:pb_set_value:"
780 "Invalid type for field "
781 << field_name <<
", expects Integer, got "
782 << PLEXIL::valueTypeName(value.valueType()));
783 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
784 m_execInterface.notifyOfExternalEvent();
789 if (field->is_repeated()) {
791 refl->AddInt32(msg, field, v);
793 refl->SetRepeatedInt32(msg, field, partial_index, v);
796 refl->SetInt32(msg, field, v);
801 case FieldDescriptor::TYPE_BOOL:
802 if (value.valueType() != PLEXIL::BOOLEAN_TYPE) {
803 warn(
"ProtobufCommAdapter:pb_set_value:"
804 "Invalid type for field "
805 << field_name <<
", expects Boolean, got "
806 << PLEXIL::valueTypeName(value.valueType()));
807 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
808 m_execInterface.notifyOfExternalEvent();
813 if (field->is_repeated()) {
815 refl->AddBool(msg, field, v);
817 refl->SetRepeatedBool(msg, field, partial_index, v);
820 refl->SetBool(msg, field, v);
825 case FieldDescriptor::TYPE_STRING:
826 if (value.valueType() != PLEXIL::STRING_TYPE) {
827 warn(
"ProtobufCommAdapter:pb_set_value:"
828 "Invalid type for field "
829 << field_name <<
", expects String, got " << PLEXIL::valueTypeName(value.valueType()));
830 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
831 m_execInterface.notifyOfExternalEvent();
836 if (field->is_repeated()) {
838 refl->AddString(msg, field, v);
840 refl->SetRepeatedString(msg, field, partial_index, v);
843 refl->SetString(msg, field, v);
848 case FieldDescriptor::TYPE_MESSAGE:
852 case FieldDescriptor::TYPE_BYTES:
853 warn(
"ProtobufCommAdapter:pb_set_value: cannot set byte field.");
854 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
855 m_execInterface.notifyOfExternalEvent();
858 case FieldDescriptor::TYPE_FIXED32:
859 case FieldDescriptor::TYPE_UINT32:
860 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
861 warn(
"ProtobufCommAdapter:pb_set_value:"
862 "Invalid type for field "
863 << field_name <<
", expects Integer, got "
864 << PLEXIL::valueTypeName(value.valueType()));
865 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
866 m_execInterface.notifyOfExternalEvent();
871 if (field->is_repeated()) {
873 refl->AddUInt32(msg, field, v);
875 refl->SetRepeatedUInt32(msg, field, partial_index, v);
878 refl->SetUInt32(msg, field, v);
883 case FieldDescriptor::TYPE_ENUM:
884 if (value.valueType() != PLEXIL::STRING_TYPE) {
885 warn(
"ProtobufCommAdapter:pb_set_value:"
886 "Invalid type for field "
887 << field_name <<
", expects String, got " << PLEXIL::valueTypeName(value.valueType()));
888 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
889 m_execInterface.notifyOfExternalEvent();
895 const EnumDescriptor * enumdesc = field->enum_type();
896 const EnumValueDescriptor *enumval = enumdesc->FindValueByName(v);
898 if (field->is_repeated()) {
900 refl->AddEnum(msg, field, enumval);
902 refl->SetRepeatedEnum(msg, field, partial_index, enumval);
905 refl->SetEnum(msg, field, enumval);
908 warn(
"ProtobufCommAdapter:pb_set_value:"
909 "Invalid enum value '"
910 << v <<
"' for field " << field_name);
911 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
912 m_execInterface.notifyOfExternalEvent();
919 }
catch (std::logic_error &e) {
920 warn(
"ProtobufCommAdapter:pb_set_value:"
921 "Failed to set field "
922 << field_name <<
": " << e.what());
923 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
924 m_execInterface.notifyOfExternalEvent();
927 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
928 m_execInterface.notifyOfExternalEvent();
932ProtobufCommPlexilAdapter::pb_get_value(PLEXIL::Command *cmd, PLEXIL::ValueType value_type)
934 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
935 if (!verify_args(args,
936 "ProtobufCommAdapter:pb_get_value",
937 {{
"msg_id", PLEXIL::STRING_TYPE}, {
"field", PLEXIL::STRING_TYPE}})) {
938 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
939 m_execInterface.notifyOfExternalEvent();
944 std::string field_name;
945 args[0].getValue(msg_id);
946 args[1].getValue(field_name);
948 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
950 warn(
"ProtobufCommAdapter:pb_get_value:"
951 <<
" Unknown message " << msg_id);
952 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
953 m_execInterface.notifyOfExternalEvent();
957 const FieldDescriptor * field =
nullptr;
958 google::protobuf::Message *msg = m.get();
960 std::string partial_name;
961 long int partial_index = -1;
963 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_get_value")) {
964 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
965 m_execInterface.notifyOfExternalEvent();
970 warn(
"ProtobufCommAdapter:pb_get_value:"
971 <<
" Unknown field " << field_name <<
" for message " << msg_id);
972 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
973 m_execInterface.notifyOfExternalEvent();
977 if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
978 warn(
"ProtobufCommAdapter:pb_get_value:"
979 <<
" Final sub-field " << field_name <<
" is a message");
980 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
981 m_execInterface.notifyOfExternalEvent();
985 const Reflection *refl = msg->GetReflection();
988 switch (field->type()) {
989 case FieldDescriptor::TYPE_DOUBLE:
990 case FieldDescriptor::TYPE_FLOAT:
991 if (value_type != PLEXIL::REAL_TYPE) {
992 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
993 <<
" not of expected type Real");
994 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
995 m_execInterface.notifyOfExternalEvent();
1000 case FieldDescriptor::TYPE_INT64:
1001 case FieldDescriptor::TYPE_SFIXED64:
1002 case FieldDescriptor::TYPE_SINT64:
1003 case FieldDescriptor::TYPE_UINT64:
1004 case FieldDescriptor::TYPE_FIXED64:
1005 case FieldDescriptor::TYPE_INT32:
1006 case FieldDescriptor::TYPE_SFIXED32:
1007 case FieldDescriptor::TYPE_SINT32:
1008 case FieldDescriptor::TYPE_UINT32:
1009 case FieldDescriptor::TYPE_FIXED32:
1010 if (value_type != PLEXIL::INTEGER_TYPE) {
1011 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1012 <<
" not of expected type Integer");
1013 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1014 m_execInterface.notifyOfExternalEvent();
1019 case FieldDescriptor::TYPE_BOOL:
1020 if (value_type != PLEXIL::BOOLEAN_TYPE) {
1021 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1022 <<
" not of expected type Boolean");
1023 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1024 m_execInterface.notifyOfExternalEvent();
1029 case FieldDescriptor::TYPE_STRING:
1030 case FieldDescriptor::TYPE_ENUM:
1031 if (value_type != PLEXIL::STRING_TYPE) {
1032 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1033 <<
" not of expected type String");
1034 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1035 m_execInterface.notifyOfExternalEvent();
1041 if (value_type != PLEXIL::STRING_TYPE) {
1042 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1043 <<
" of unsupported protobuf type");
1044 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1045 m_execInterface.notifyOfExternalEvent();
1051 if (field->is_repeated()) {
1052 if (partial_index >= refl->FieldSize(*msg, field)) {
1053 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
"Index " << partial_index
1054 <<
" for " << partial_name <<
" is out of bounds");
1055 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1056 m_execInterface.notifyOfExternalEvent();
1060 switch (field->type()) {
1061 case FieldDescriptor::TYPE_DOUBLE:
1062 m_execInterface.handleCommandReturn(cmd,
1064 refl->GetRepeatedDouble(*msg, field, partial_index)));
1066 case FieldDescriptor::TYPE_FLOAT:
1067 m_execInterface.handleCommandReturn(cmd,
1069 refl->GetRepeatedFloat(*msg, field, partial_index)));
1071 case FieldDescriptor::TYPE_UINT64:
1072 case FieldDescriptor::TYPE_FIXED64:
1073 m_execInterface.handleCommandReturn(
1074 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedUInt64(*msg, field, partial_index)));
1076 case FieldDescriptor::TYPE_UINT32:
1077 case FieldDescriptor::TYPE_FIXED32:
1078 m_execInterface.handleCommandReturn(
1079 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedUInt32(*msg, field, partial_index)));
1081 case FieldDescriptor::TYPE_BOOL:
1082 m_execInterface.handleCommandReturn(
1083 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedBool(*msg, field, partial_index)));
1085 case FieldDescriptor::TYPE_STRING:
1086 m_execInterface.handleCommandReturn(cmd,
1088 refl->GetRepeatedString(*msg, field, partial_index)));
1090 case FieldDescriptor::TYPE_ENUM:
1091 m_execInterface.handleCommandReturn(
1092 cmd, PLEXIL::Value(refl->GetRepeatedEnum(*msg, field, partial_index)->name()));
1094 case FieldDescriptor::TYPE_SFIXED32:
1095 case FieldDescriptor::TYPE_INT32:
1096 case FieldDescriptor::TYPE_SINT32:
1097 m_execInterface.handleCommandReturn(
1098 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedInt32(*msg, field, partial_index)));
1100 case FieldDescriptor::TYPE_SFIXED64:
1101 case FieldDescriptor::TYPE_SINT64:
1102 case FieldDescriptor::TYPE_INT64:
1103 m_execInterface.handleCommandReturn(
1104 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedInt64(*msg, field, partial_index)));
1110 if (!refl->HasField(*msg, field)) {
1111 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1113 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1114 m_execInterface.notifyOfExternalEvent();
1119 switch (field->type()) {
1120 case FieldDescriptor::TYPE_DOUBLE:
1121 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetDouble(*msg, field)));
1123 case FieldDescriptor::TYPE_FLOAT:
1124 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetFloat(*msg, field)));
1126 case FieldDescriptor::TYPE_INT64:
1127 case FieldDescriptor::TYPE_SFIXED64:
1128 case FieldDescriptor::TYPE_SINT64:
1129 m_execInterface.handleCommandReturn(cmd,
1131 (PLEXIL::Integer)refl->GetInt64(*msg, field)));
1133 case FieldDescriptor::TYPE_UINT64:
1134 case FieldDescriptor::TYPE_FIXED64:
1135 m_execInterface.handleCommandReturn(cmd,
1137 (PLEXIL::Integer)refl->GetUInt64(*msg, field)));
1139 case FieldDescriptor::TYPE_INT32:
1140 case FieldDescriptor::TYPE_SFIXED32:
1141 case FieldDescriptor::TYPE_SINT32:
1142 m_execInterface.handleCommandReturn(cmd,
1144 (PLEXIL::Integer)refl->GetInt32(*msg, field)));
1146 case FieldDescriptor::TYPE_UINT32:
1147 case FieldDescriptor::TYPE_FIXED32:
1148 m_execInterface.handleCommandReturn(cmd,
1150 (PLEXIL::Integer)refl->GetUInt32(*msg, field)));
1152 case FieldDescriptor::TYPE_BOOL:
1153 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetBool(*msg, field)));
1155 case FieldDescriptor::TYPE_STRING:
1156 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetString(*msg, field)));
1159 case FieldDescriptor::TYPE_ENUM:
1160 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetEnum(*msg, field)->name()));
1164 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
" invalid value type for "
1166 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1167 m_execInterface.notifyOfExternalEvent();
1172 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1173 m_execInterface.notifyOfExternalEvent();
1177ProtobufCommPlexilAdapter::pb_get_length(PLEXIL::Command *cmd)
1179 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1180 if (!verify_args(args,
1181 "ProtobufCommAdapter:pb_get_length",
1182 {{
"msg_id", PLEXIL::STRING_TYPE}, {
"field", PLEXIL::STRING_TYPE}})) {
1183 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1184 m_execInterface.notifyOfExternalEvent();
1189 std::string field_name;
1190 args[0].getValue(msg_id);
1191 args[1].getValue(field_name);
1193 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1195 warn(
"ProtobufCommAdapter:pb_get_length:"
1196 <<
" Unknown message " << msg_id);
1197 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1198 m_execInterface.notifyOfExternalEvent();
1202 const FieldDescriptor * field =
nullptr;
1203 google::protobuf::Message *msg = m.get();
1205 std::string partial_name;
1206 long int partial_index = -1;
1208 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_get_length")) {
1209 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1210 m_execInterface.notifyOfExternalEvent();
1215 warn(
"ProtobufCommAdapter:pb_get_length:"
1216 <<
" Unknown field " << field_name <<
" for message " << msg_id);
1217 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1218 m_execInterface.notifyOfExternalEvent();
1222 if (!field->is_repeated()) {
1223 warn(
"ProtobufCommAdapter:pb_get_length:"
1224 <<
" Field " << field_name <<
" is not a repeated field in " << msg_id);
1225 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1226 m_execInterface.notifyOfExternalEvent();
1229 const Reflection *refl = msg->GetReflection();
1231 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->FieldSize(*msg, field)));
1232 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1233 m_execInterface.notifyOfExternalEvent();
1237ProtobufCommPlexilAdapter::pb_has_field(PLEXIL::Command *cmd)
1239 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1240 if (!verify_args(args,
1241 "ProtobufCommAdapter:pb_has_field",
1242 {{
"msg_id", PLEXIL::STRING_TYPE}, {
"field", PLEXIL::STRING_TYPE}})) {
1243 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1244 m_execInterface.notifyOfExternalEvent();
1249 std::string field_name;
1250 args[0].getValue(msg_id);
1251 args[1].getValue(field_name);
1253 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1255 warn(
"ProtobufCommAdapter:pb_has_field:"
1256 <<
" Unknown message " << msg_id);
1257 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1258 m_execInterface.notifyOfExternalEvent();
1262 const FieldDescriptor * field =
nullptr;
1263 google::protobuf::Message *msg = m.get();
1265 std::string partial_name;
1266 long int partial_index = -1;
1268 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_has_field")) {
1269 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(
false));
1270 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1271 m_execInterface.notifyOfExternalEvent();
1276 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(
false));
1277 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1278 m_execInterface.notifyOfExternalEvent();
1282 const Reflection *refl = msg->GetReflection();
1284 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->HasField(*msg, field)));
1285 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1286 m_execInterface.notifyOfExternalEvent();
1290ProtobufCommPlexilAdapter::pb_tostring(PLEXIL::Command *cmd)
1292 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1293 if (!verify_args(args,
"ProtobufCommAdapter:pb_tostring", {{
"msg_id", PLEXIL::STRING_TYPE}})) {
1294 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1295 m_execInterface.notifyOfExternalEvent();
1300 args[0].getValue(msg_id);
1302 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1304 warn(
"ProtobufCommAdapter:pb_tostring:"
1305 <<
" Unknown message " << msg_id);
1306 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1307 m_execInterface.notifyOfExternalEvent();
1311 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(m->DebugString()));
1312 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1313 m_execInterface.notifyOfExternalEvent();
1317ProtobufCommPlexilAdapter::pb_broadcast(PLEXIL::Command *cmd)
1319 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1320 if (!verify_args(args,
1321 "ProtobufCommAdapter:pb_broadcast",
1322 {{
"peer_id", PLEXIL::INTEGER_TYPE}, {
"msg_id", PLEXIL::STRING_TYPE}})) {
1323 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1324 m_execInterface.notifyOfExternalEvent();
1330 args[0].getValue(peer_id);
1331 args[1].getValue(msg_id);
1333 if (peers_.find(peer_id) == peers_.end()) {
1334 warn(
"ProtobufCommAdapter:pb_broadcast:"
1335 <<
" Unknown peer " << peer_id);
1336 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1337 m_execInterface.notifyOfExternalEvent();
1341 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1343 warn(
"ProtobufCommAdapter:pb_broadcast:"
1344 <<
" Unknown message " << msg_id);
1345 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1346 m_execInterface.notifyOfExternalEvent();
1350 std::lock_guard<std::mutex> lock(map_mutex_);
1354 peers_[peer_id]->send(m);
1355 }
catch (google::protobuf::FatalException &e) {
1356 warn(
"ProtobufCommAdapter:pb_broadcast:"
1357 <<
" Failed to send message " << msg_id <<
"(" << e.what() <<
")");
1358 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1359 m_execInterface.notifyOfExternalEvent();
1362 warn(
"ProtobufCommAdapter:pb_broadcast:"
1363 <<
" Failed to send message " << msg_id <<
"(" << e.
what_no_backtrace() <<
")");
1364 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1365 m_execInterface.notifyOfExternalEvent();
1367 }
catch (std::runtime_error &e) {
1368 warn(
"ProtobufCommAdapter:pb_broadcast:"
1369 <<
" Failed to message " << msg_id <<
"(" << e.what() <<
")");
1370 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1371 m_execInterface.notifyOfExternalEvent();
1376 std::lock_guard<std::mutex> lock(queue_mutex_);
1377 messages_.erase(msg_id);
1380 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1381 m_execInterface.notifyOfExternalEvent();
1393ProtobufCommPlexilAdapter::pb_peer_create_local_crypto(
1394 PLEXIL::Command * cmd,
1395 const std::vector<PLEXIL::Value> *override_args)
1397 std::vector<PLEXIL::Value>
const &args = override_args ? *override_args : cmd->getArgValues();
1399 if (!verify_args(args,
1400 "ProtobufCommAdapter:pb_peer_create_local_crypto",
1401 {{
"address", PLEXIL::STRING_TYPE},
1402 {
"send_port", PLEXIL::INTEGER_TYPE},
1403 {
"recv_port", PLEXIL::INTEGER_TYPE},
1404 {
"crypto_key", PLEXIL::STRING_TYPE},
1405 {
"cipher", PLEXIL::STRING_TYPE}})) {
1406 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1407 m_execInterface.notifyOfExternalEvent();
1411 std::string address;
1412 int send_port, recv_port;
1413 std::string crypto_key, cipher;
1415 args[0].getValue(address);
1416 args[1].getValue(send_port);
1417 args[2].getValue(recv_port);
1418 args[3].getValue(crypto_key);
1419 args[4].getValue(cipher);
1422 recv_port = send_port;
1424 if (send_port > 0) {
1425 std::shared_ptr<ProtobufBroadcastPeer> peer =
1426 std::make_shared<ProtobufBroadcastPeer>(address,
1427 (
unsigned short)send_port,
1428 (
unsigned short)recv_port,
1429 &*message_register_,
1435 std::lock_guard<std::mutex> lock(map_mutex_);
1436 peer_id = ++next_client_id_;
1437 peers_[peer_id] = peer;
1440 peer->signal_received().connect(
1441 boost::bind(&ProtobufCommPlexilAdapter::handle_peer_msg,
this, peer_id, _1, _2, _3, _4));
1442 peer->signal_recv_error().connect(
1443 boost::bind(&ProtobufCommPlexilAdapter::handle_peer_recv_error,
this, peer_id, _1, _2));
1444 peer->signal_send_error().connect(
1445 boost::bind(&ProtobufCommPlexilAdapter::handle_peer_send_error,
this, peer_id, _1));
1447 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(peer_id));
1448 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1449 m_execInterface.notifyOfExternalEvent();
1451 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1452 m_execInterface.notifyOfExternalEvent();
1464ProtobufCommPlexilAdapter::pb_peer_create_crypto(PLEXIL::Command *cmd)
1466 std::vector<PLEXIL::Value>
const &in_args = cmd->getArgValues();
1467 if (!verify_args(in_args,
1468 "pb_peer_create_crypto",
1469 {{
"address", PLEXIL::STRING_TYPE},
1470 {
"port", PLEXIL::INTEGER_TYPE},
1471 {
"crypto_key", PLEXIL::STRING_TYPE},
1472 {
"cipher", PLEXIL::STRING_TYPE}})) {
1473 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1474 m_execInterface.notifyOfExternalEvent();
1478 std::vector<PLEXIL::Value> args{in_args[0], in_args[1], in_args[1], in_args[2], in_args[3]};
1480 pb_peer_create_local_crypto(cmd, &args);
1489ProtobufCommPlexilAdapter::pb_peer_create(PLEXIL::Command *cmd)
1491 std::vector<PLEXIL::Value>
const &in_args = cmd->getArgValues();
1492 if (!verify_args(in_args,
1494 {{
"address", PLEXIL::STRING_TYPE}, {
"port", PLEXIL::INTEGER_TYPE}})) {
1495 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1496 m_execInterface.notifyOfExternalEvent();
1500 std::vector<PLEXIL::Value> args{
1501 in_args[0], in_args[1], in_args[1], PLEXIL::Value(
""), PLEXIL::Value(
"")};
1503 pb_peer_create_local_crypto(cmd, &args);
1513ProtobufCommPlexilAdapter::pb_peer_create_local(PLEXIL::Command *cmd)
1515 std::vector<PLEXIL::Value>
const &in_args = cmd->getArgValues();
1516 if (!verify_args(in_args,
1517 "pb_peer_create_local",
1518 {{
"address", PLEXIL::STRING_TYPE},
1519 {
"send_port", PLEXIL::INTEGER_TYPE},
1520 {
"recv_port", PLEXIL::INTEGER_TYPE}})) {
1521 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1522 m_execInterface.notifyOfExternalEvent();
1526 std::vector<PLEXIL::Value> args{
1527 in_args[0], in_args[1], in_args[2], PLEXIL::Value(
""), PLEXIL::Value(
"")};
1529 pb_peer_create_local_crypto(cmd, &args);
1536ProtobufCommPlexilAdapter::pb_peer_destroy(PLEXIL::Command *cmd)
1538 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1539 if (!verify_args(args,
1540 "ProtobufCommAdapter:pb_peer_destroy",
1541 {{
"peer_id", PLEXIL::INTEGER_TYPE}})) {
1542 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1543 m_execInterface.notifyOfExternalEvent();
1548 args[0].getValue(peer_id);
1550 peers_.erase(peer_id);
1552 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1553 m_execInterface.notifyOfExternalEvent();
1562ProtobufCommPlexilAdapter::pb_peer_setup_crypto(PLEXIL::Command *cmd)
1564 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1565 if (!verify_args(args,
1566 "ProtobufCommAdapter:pb_peer_setup_crypto",
1567 {{
"peer_id", PLEXIL::INTEGER_TYPE},
1568 {
"crypto_key", PLEXIL::STRING_TYPE},
1569 {
"cipher", PLEXIL::STRING_TYPE}})) {
1570 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1571 m_execInterface.notifyOfExternalEvent();
1576 std::string crypto_key;
1579 args[0].getValue(peer_id);
1580 args[1].getValue(crypto_key);
1581 args[2].getValue(cipher);
1583 if (peers_.find(peer_id) != peers_.end()) {
1584 peers_[peer_id]->setup_crypto(crypto_key, cipher);
1587 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1588 m_execInterface.notifyOfExternalEvent();
1598ProtobufCommPlexilAdapter::handle_peer_msg(
int peer_id,
1599 boost::asio::ip::udp::endpoint & endpoint,
1600 uint16_t component_id,
1602 std::shared_ptr<google::protobuf::Message> msg)
1605 .from_host = endpoint.address().to_string(),
1606 .from_port = endpoint.port(),
1609 add_message(msg->GetTypeName(), std::move(m));
1610 proc_queue(msg->GetTypeName());
1618ProtobufCommPlexilAdapter::handle_peer_recv_error(
int peer_id,
1619 boost::asio::ip::udp::endpoint &endpoint,
1623 logger_->
log_warn(
"PlexilProtobuf",
1624 "Failed to receive peer message from %s:%u: %s",
1625 endpoint.address().to_string().c_str(),
1635ProtobufCommPlexilAdapter::handle_peer_send_error(
int peer_id, std::string msg)
1638 logger_->
log_warn(
"PlexilProtobuf",
"Failed to send peer message: %s", msg.c_str());
1644initProtobufCommAdapter()
Interface adapter to provide logging facilities.
virtual bool initialize()
Initialize adapter.
virtual bool start()
Start adapter.
void executeCommand(PLEXIL::Command *cmd)
Perform given command.
void invokeAbort(PLEXIL::Command *cmd)
Abort currently running execution.
virtual bool shutdown()
Shut adapter down.
virtual ~ProtobufCommPlexilAdapter()
Destructor.
virtual bool reset()
Reset adapter.
ProtobufCommPlexilAdapter(PLEXIL::AdapterExecInterface &execInterface)
Constructor.
virtual bool stop()
Stop adapter.
This is supposed to be the central clock in Fawkes.
Interface for configuration handling.
Base class for exceptions in Fawkes.
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
A class for handling time.
Fawkes library namespace.