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> 38 using namespace protobuf_comm;
39 using namespace google::protobuf;
50 : InterfaceAdapter(execInterface)
60 pugi::xml_node
const xml)
61 : InterfaceAdapter(execInterface, xml)
76 logger_ = reinterpret_cast<fawkes::Logger *>(m_execInterface.getProperty(
"::Fawkes::Logger"));
78 reinterpret_cast<fawkes::Configuration *>(m_execInterface.getProperty(
"::Fawkes::Config"));
79 clock_ = reinterpret_cast<fawkes::Clock *>(m_execInterface.getProperty(
"::Fawkes::Clock"));
81 std::string cfg_proto_dir = get_xml_config_value(getXml(),
"protos");
82 replace_tokens(cfg_proto_dir);
84 std::vector<std::string> cfg_proto_dirs{cfg_proto_dir};
85 logger_->
log_info(
"PlexilProtobuf",
"Protobuf message spec dir: %s", cfg_proto_dirs[0].c_str());
90 message_register_ = std::make_shared<MessageRegister>(cfg_proto_dirs);
92 namespace p = std::placeholders;
94 {
"ReceiveCommand", std::bind(&ProtobufCommPlexilAdapter::proc_receive_command,
this, p::_1)},
95 {
"GetParameter", std::bind(&ProtobufCommPlexilAdapter::proc_get_param_command,
this, p::_1)},
96 {
"SendReturnValue", std::bind(&ProtobufCommPlexilAdapter::proc_send_rv_command,
this, p::_1)},
97 {
"pb_create", std::bind(&ProtobufCommPlexilAdapter::pb_create,
this, p::_1)},
98 {
"pb_destroy", std::bind(&ProtobufCommPlexilAdapter::pb_destroy,
this, p::_1)},
99 {
"pb_set_value", std::bind(&ProtobufCommPlexilAdapter::pb_set_value,
this, p::_1)},
101 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::INTEGER_TYPE)},
103 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::REAL_TYPE)},
105 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::BOOLEAN_TYPE)},
107 std::bind(&ProtobufCommPlexilAdapter::pb_get_value,
this, p::_1, PLEXIL::STRING_TYPE)},
108 {
"pb_get_length", std::bind(&ProtobufCommPlexilAdapter::pb_get_length,
this, p::_1)},
109 {
"pb_has_field", std::bind(&ProtobufCommPlexilAdapter::pb_has_field,
this, p::_1)},
110 {
"pb_broadcast", std::bind(&ProtobufCommPlexilAdapter::pb_broadcast,
this, p::_1)},
111 {
"pb_tostring", std::bind(&ProtobufCommPlexilAdapter::pb_tostring,
this, p::_1)},
112 {
"pb_peer_create", std::bind(&ProtobufCommPlexilAdapter::pb_peer_create,
this, p::_1)},
113 {
"pb_peer_destroy", std::bind(&ProtobufCommPlexilAdapter::pb_get_length,
this, p::_1)},
114 {
"pb_peer_create_local",
115 std::bind(&ProtobufCommPlexilAdapter::pb_peer_create_local,
this, p::_1)},
116 {
"pb_peer_create_crypto",
117 std::bind(&ProtobufCommPlexilAdapter::pb_peer_create_crypto,
this, p::_1)},
118 {
"pb_peer_create_local_crypto",
119 std::bind(&ProtobufCommPlexilAdapter::pb_peer_create_local_crypto,
this, p::_1,
nullptr)},
120 {
"pb_peer_setup_crypto",
121 std::bind(&ProtobufCommPlexilAdapter::pb_peer_setup_crypto,
this, p::_1)},
124 for (
const auto &c : commands_) {
125 PLEXIL::g_configuration->registerCommandInterface(c.first,
this);
146 std::lock_guard<std::mutex> lock(queue_mutex_);
177 std::string
const &name = cmd->getName();
181 auto c = commands_.find(name);
182 if (c != commands_.end()) {
185 warn(
"ProtobufCommAdapter:executeCommand: called for unknown" 188 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
189 m_execInterface.notifyOfExternalEvent();
194 ProtobufCommPlexilAdapter::proc_receive_command(PLEXIL::Command *cmd)
196 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
197 if (args.size() != 1) {
198 warn(
"ProtobufCommAdapter: The ReceiveCommand" 199 " command requires exactly one argument");
200 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
201 m_execInterface.notifyOfExternalEvent();
205 if (args.front().valueType() != PLEXIL::STRING_TYPE) {
206 warn(
"ProtobufCommAdapter: The argument to the ReceiveCommand" 208 << args.front() <<
", is not a string");
209 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
210 m_execInterface.notifyOfExternalEvent();
214 std::string msg_type;
215 if (!args.front().getValue(msg_type)) {
216 warn(
"ProtobufCommAdapter: message type is unknown");
217 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
218 m_execInterface.notifyOfExternalEvent();
222 add_recipient(msg_type, cmd);
223 proc_queue(msg_type);
225 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SENT_TO_SYSTEM);
226 m_execInterface.notifyOfExternalEvent();
230 ProtobufCommPlexilAdapter::proc_get_param_command(PLEXIL::Command *cmd)
232 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
233 if (args.size() < 1 || args.size() > 2) {
234 warn(
"ProtobufCommAdapter:GetParameter: " 235 "Command requires either one or two arguments");
236 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
237 m_execInterface.notifyOfExternalEvent();
241 if (args.front().valueType() != PLEXIL::STRING_TYPE) {
242 warn(
"ProtobufCommAdapter:GetParameter: first argument " 244 << args.front() <<
"' is not a string");
245 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
246 m_execInterface.notifyOfExternalEvent();
251 if (!args.front().getValue(msg_id)) {
252 warn(
"ProtobufCommAdapter:GetParameter: message ID is unknown");
253 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
254 m_execInterface.notifyOfExternalEvent();
258 std::lock_guard<std::mutex> lock(queue_mutex_);
260 if (messages_.find(msg_id) == messages_.end()) {
261 warn(
"ProtobufCommAdapter:GetParameter: message ID not in queued messages");
262 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
263 m_execInterface.notifyOfExternalEvent();
267 std::vector<PLEXIL::Value>::const_iterator it = ++args.begin();
269 if (it != args.end()) {
270 if (it->valueType() != PLEXIL::INTEGER_TYPE) {
271 warn(
"ProtobufCommAdapter:GetParameter: second argument " 273 << *it <<
"' is not an integer");
274 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
275 m_execInterface.notifyOfExternalEvent();
279 if (!it->getValue(
id)) {
280 warn(
"ProtobufCommAdapter:GetParameter: second argument is unknown");
281 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
282 m_execInterface.notifyOfExternalEvent();
286 if (id < 0 || id > 3) {
287 warn(
"ProtobufCommAdapter:GetParameter: second argument " 289 << *it <<
"' is not a valid index (must be 0..3)");
290 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
291 m_execInterface.notifyOfExternalEvent();
296 const message_meta &msgmeta = messages_[msg_id];
299 case 0: m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msg_id));
break;
300 case 1: m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msgmeta.from_host));
break;
301 case 2: m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msgmeta.from_port));
break;
303 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msgmeta.time_received.in_sec()));
307 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
308 m_execInterface.notifyOfExternalEvent();
312 ProtobufCommPlexilAdapter::proc_send_rv_command(PLEXIL::Command *cmd)
314 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
315 if (args.size() == 0) {
316 warn(
"ProtobufCommAdapter:SendReturnValue: The SendReturnValue" 317 " command requires at least one argument");
318 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
319 m_execInterface.notifyOfExternalEvent();
323 if (args.front().valueType() != PLEXIL::STRING_TYPE) {
324 warn(
"ProtobufCommAdapter:SendReturnValue: The argument to the " 325 "SendReturnValue command, " 326 << args.front() <<
", is not a string");
327 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
328 m_execInterface.notifyOfExternalEvent();
333 if (!args.front().getValue(msg_id)) {
334 warn(
"ProtobufCommAdapter:SendReturnValue: message ID is unknown");
335 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
336 m_execInterface.notifyOfExternalEvent();
340 release_message(msg_id);
342 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
343 m_execInterface.notifyOfExternalEvent();
352 m_execInterface.handleCommandAbortAck(cmd,
false);
353 m_execInterface.notifyOfExternalEvent();
357 ProtobufCommPlexilAdapter::add_recipient(
const std::string &msg_type, PLEXIL::Command *cmd)
359 std::lock_guard<std::mutex> lock(queue_mutex_);
360 queue_entry & q = get_queue(msg_type);
361 q.recipients.push_back(cmd);
365 ProtobufCommPlexilAdapter::remove_recipient(
const std::string &msg_type, PLEXIL::Command *cmd)
367 std::lock_guard<std::mutex> lock(queue_mutex_);
368 queue_entry & q = get_queue(msg_type);
369 q.recipients.erase(std::remove(q.recipients.begin(), q.recipients.end(), cmd),
374 ProtobufCommPlexilAdapter::add_message(
const std::string &msg_type, message_meta &&msg)
376 std::lock_guard<std::mutex> lock(queue_mutex_);
377 queue_entry & q = get_queue(msg_type);
378 std::string msg_id = gen_msgid(msg_type);
380 messages_[msg_id] = std::move(msg);
382 q.messages.push_back(msg_id);
386 ProtobufCommPlexilAdapter::release_message(
const std::string &msg_id)
388 std::lock_guard<std::mutex> lock(queue_mutex_);
390 std::string::size_type colon_pos = msg_id.find(
':');
391 if (colon_pos != std::string::npos) {
392 std::string msg_type{msg_id.substr(0, colon_pos)};
393 queue_entry &q = get_queue(msg_type);
395 q.messages.erase(std::remove(q.messages.begin(), q.messages.end(), msg_id), q.messages.end());
396 messages_.erase(msg_id);
400 std::shared_ptr<google::protobuf::Message>
401 ProtobufCommPlexilAdapter::get_message(
const std::string &msg_id)
403 std::shared_ptr<google::protobuf::Message> m;
405 std::lock_guard<std::mutex> lock(queue_mutex_);
407 if (messages_.find(msg_id) != messages_.end()) {
408 m = messages_[msg_id].message;
414 ProtobufCommPlexilAdapter::gen_msgid(
const std::string &msg_type)
416 unsigned long int id = ++msg_counter_;
417 return msg_type +
":" + std::to_string(
id);
421 ProtobufCommPlexilAdapter::proc_queue(
const std::string &msg_type)
423 std::lock_guard<std::mutex> lock(queue_mutex_);
424 queue_entry & q = get_queue(msg_type);
425 auto mi = q.messages.begin();
426 auto ri = q.recipients.begin();
427 bool notify = !q.messages.empty() && !q.recipients.empty();
428 while (mi != q.messages.end() && ri != q.recipients.end()) {
429 m_execInterface.handleCommandReturn(*ri, *mi);
430 ri = q.recipients.erase(ri);
431 mi = q.messages.erase(mi);
434 m_execInterface.notifyOfExternalEvent();
438 ProtobufCommPlexilAdapter::queue_entry &
439 ProtobufCommPlexilAdapter::get_queue(
const std::string &msg_type)
441 auto q = queue_.find(msg_type);
442 if (q != queue_.end()) {
445 auto new_q = queue_.insert(std::make_pair(msg_type, queue_entry()));
446 return new_q.first->second;
453 ProtobufCommPlexilAdapter::pb_create(PLEXIL::Command *cmd)
455 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
456 if (!verify_args(args,
"ProtobufCommAdapter:pb_create", {{
"msg_type", PLEXIL::STRING_TYPE}})) {
457 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
458 m_execInterface.notifyOfExternalEvent();
462 std::string msg_type;
463 args[0].getValue(msg_type);
465 std::lock_guard<std::mutex> lock(queue_mutex_);
466 std::string msg_id = gen_msgid(msg_type);
469 std::shared_ptr<google::protobuf::Message> m = message_register_->new_message_for(msg_type);
471 message_meta msgmeta{.time_received =
fawkes::Time(clock_),
474 .message = std::shared_ptr<google::protobuf::Message>(m)};
476 messages_[msg_id] = std::move(msgmeta);
478 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(msg_id));
479 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
480 m_execInterface.notifyOfExternalEvent();
481 }
catch (std::runtime_error &e) {
483 "Cannot create message of type %s: %s",
486 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
487 m_execInterface.notifyOfExternalEvent();
494 ProtobufCommPlexilAdapter::pb_destroy(PLEXIL::Command *cmd)
496 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
497 if (!verify_args(args,
"ProtobufCommAdapter:pb_destroy", {{
"msg_id", PLEXIL::STRING_TYPE}})) {
498 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
499 m_execInterface.notifyOfExternalEvent();
504 args[0].getValue(msg_id);
506 std::lock_guard<std::mutex> lock(queue_mutex_);
507 messages_.erase(msg_id);
510 static std::pair<std::string, long int>
511 parse_field_name(
const std::string &field_name,
const std::string &func)
516 std::string::size_type opening = field_name.find(
'[');
517 if (opening != std::string::npos) {
518 std::string::size_type closing = field_name.find(
']', opening);
519 if (closing != std::string::npos) {
520 field = field_name.substr(0, opening);
521 std::string idx_str = field_name.substr(opening + 1, closing - opening - 1);
522 if (idx_str.empty()) {
523 index = std::numeric_limits<long int>::max();
525 index = std::stol(idx_str);
528 warn(
"ProtobufCommAdapter:" << func <<
":" 529 <<
" Missing closing bracket in " << field_name);
534 return std::make_pair(field, index);
538 traverse_field(google::protobuf::Message *&msg,
539 const std::string & field_name,
540 const FieldDescriptor *& field,
541 std::string & partial_name,
542 long int & partial_index,
543 const std::string & func)
546 std::vector<std::string> field_path = str_split(field_name,
'.');
547 for (
size_t i = 0; i < field_path.size(); ++i) {
548 std::pair<std::string, long int> parsed_field = parse_field_name(field_path[i], func);
549 partial_name = parsed_field.first;
550 partial_index = parsed_field.second;
552 if (partial_name.empty()) {
553 warn(
"ProtobufCommAdapter:" << func <<
":" 554 <<
" Invalid sub-field " << field_path[i]);
558 const Descriptor *desc = msg->GetDescriptor();
559 field = desc->FindFieldByName(partial_name);
561 warn(
"ProtobufCommAdapter:" << func <<
":" 562 <<
" Field " << partial_name <<
" not found");
566 if (partial_index >= 0 && !field->is_repeated()) {
567 warn(
"ProtobufCommAdapter:" << func <<
":" 568 <<
" Index for non-repeated field " << partial_name);
571 }
else if (partial_index < 0 && field->is_repeated()) {
572 warn(
"ProtobufCommAdapter:" << func <<
":" 573 <<
" No index for repeated field " << partial_name);
577 const Reflection *refl = msg->GetReflection();
583 if (field->is_repeated() && partial_index >= 0
584 && partial_index == refl->FieldSize(*msg, field)) {
585 partial_index = std::numeric_limits<long int>::max();
588 if (partial_index >= 0 && partial_index < std::numeric_limits<long int>::max()
589 && partial_index >= refl->FieldSize(*msg, field)) {
590 warn(
"ProtobufCommAdapter:" << func <<
":" 591 <<
" Index " << partial_index <<
" out of bounds for " 596 if (i < (field_path.size() - 1)) {
597 if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
598 warn(
"ProtobufCommAdapter:" << func <<
":" 599 <<
" Sub-field " << field_path[i] <<
" is not a message");
603 if (field->is_repeated()) {
604 if (partial_index == std::numeric_limits<long int>::max()) {
605 msg = refl->AddMessage(msg, field);
608 msg = refl->MutableRepeatedMessage(msg, field, partial_index);
611 msg = refl->MutableMessage(msg, field);
619 ProtobufCommPlexilAdapter::pb_set_value(PLEXIL::Command *cmd)
621 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
622 if (!verify_args(args,
623 "ProtobufCommAdapter:pb_set_value",
624 {{
"msg_id", PLEXIL::STRING_TYPE},
625 {
"field", PLEXIL::STRING_TYPE},
626 {
"value", PLEXIL::UNKNOWN_TYPE}})) {
627 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
628 m_execInterface.notifyOfExternalEvent();
633 std::string field_name;
635 args[0].getValue(msg_id);
636 args[1].getValue(field_name);
639 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
641 warn(
"ProtobufCommAdapter:pb_set_value:" 642 <<
" Unknown message " << msg_id);
643 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
644 m_execInterface.notifyOfExternalEvent();
648 const FieldDescriptor * field =
nullptr;
649 google::protobuf::Message *msg = m.get();
651 std::string partial_name;
652 long int partial_index = -1;
654 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_set_value")) {
655 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
656 m_execInterface.notifyOfExternalEvent();
661 warn(
"ProtobufCommAdapter:pb_set_value:" 662 <<
" Unknown field " << field_name <<
" for message " << msg_id);
663 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
664 m_execInterface.notifyOfExternalEvent();
668 if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
669 warn(
"ProtobufCommAdapter:pb_set_value:" 670 <<
" Final sub-field " << field_name <<
" is a message");
671 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
672 m_execInterface.notifyOfExternalEvent();
676 const Reflection *refl = msg->GetReflection();
678 bool add_repeated =
false;
679 if (field->is_repeated() && partial_index == std::numeric_limits<long int>::max()) {
684 switch (field->type()) {
685 case FieldDescriptor::TYPE_DOUBLE:
686 if (value.valueType() != PLEXIL::REAL_TYPE) {
687 warn(
"ProtobufCommAdapter:pb_set_value:" 688 "Invalid type for field " 689 << field_name <<
", expects Real, got " << PLEXIL::valueTypeName(value.valueType()));
690 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
691 m_execInterface.notifyOfExternalEvent();
696 if (field->is_repeated()) {
698 refl->AddDouble(msg, field, v);
700 refl->SetRepeatedDouble(msg, field, partial_index, v);
703 refl->SetDouble(msg, field, v);
708 case FieldDescriptor::TYPE_FLOAT:
709 if (value.valueType() != PLEXIL::REAL_TYPE) {
710 warn(
"ProtobufCommAdapter:pb_set_value:" 711 "Invalid type for field " 712 << field_name <<
", expects Real, got " << PLEXIL::valueTypeName(value.valueType()));
713 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
714 m_execInterface.notifyOfExternalEvent();
719 if (field->is_repeated()) {
721 refl->AddFloat(msg, field, v);
723 refl->SetRepeatedFloat(msg, field, partial_index, v);
726 refl->SetFloat(msg, field, v);
731 case FieldDescriptor::TYPE_SFIXED64:
732 case FieldDescriptor::TYPE_SINT64:
733 case FieldDescriptor::TYPE_INT64:
734 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
735 warn(
"ProtobufCommAdapter:pb_set_value:" 736 "Invalid type for field " 737 << field_name <<
", expects Integer, got " 738 << PLEXIL::valueTypeName(value.valueType()));
739 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
740 m_execInterface.notifyOfExternalEvent();
745 refl->SetInt64(msg, field, v);
749 case FieldDescriptor::TYPE_FIXED64:
750 case FieldDescriptor::TYPE_UINT64:
751 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
752 warn(
"ProtobufCommAdapter:pb_set_value:" 753 "Invalid type for field " 754 << field_name <<
", expects Integer, got " 755 << PLEXIL::valueTypeName(value.valueType()));
756 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
757 m_execInterface.notifyOfExternalEvent();
762 if (field->is_repeated()) {
764 refl->AddUInt64(msg, field, v);
766 refl->SetRepeatedUInt64(msg, field, partial_index, v);
769 refl->SetUInt64(msg, field, v);
774 case FieldDescriptor::TYPE_SFIXED32:
775 case FieldDescriptor::TYPE_SINT32:
776 case FieldDescriptor::TYPE_INT32:
777 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
778 warn(
"ProtobufCommAdapter:pb_set_value:" 779 "Invalid type for field " 780 << field_name <<
", expects Integer, got " 781 << PLEXIL::valueTypeName(value.valueType()));
782 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
783 m_execInterface.notifyOfExternalEvent();
788 if (field->is_repeated()) {
790 refl->AddInt32(msg, field, v);
792 refl->SetRepeatedInt32(msg, field, partial_index, v);
795 refl->SetInt32(msg, field, v);
800 case FieldDescriptor::TYPE_BOOL:
801 if (value.valueType() != PLEXIL::BOOLEAN_TYPE) {
802 warn(
"ProtobufCommAdapter:pb_set_value:" 803 "Invalid type for field " 804 << field_name <<
", expects Boolean, got " 805 << PLEXIL::valueTypeName(value.valueType()));
806 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
807 m_execInterface.notifyOfExternalEvent();
812 if (field->is_repeated()) {
814 refl->AddBool(msg, field, v);
816 refl->SetRepeatedBool(msg, field, partial_index, v);
819 refl->SetBool(msg, field, v);
824 case FieldDescriptor::TYPE_STRING:
825 if (value.valueType() != PLEXIL::STRING_TYPE) {
826 warn(
"ProtobufCommAdapter:pb_set_value:" 827 "Invalid type for field " 828 << field_name <<
", expects String, got " << PLEXIL::valueTypeName(value.valueType()));
829 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
830 m_execInterface.notifyOfExternalEvent();
835 if (field->is_repeated()) {
837 refl->AddString(msg, field, v);
839 refl->SetRepeatedString(msg, field, partial_index, v);
842 refl->SetString(msg, field, v);
847 case FieldDescriptor::TYPE_MESSAGE:
851 case FieldDescriptor::TYPE_BYTES:
852 warn(
"ProtobufCommAdapter:pb_set_value: cannot set byte field.");
853 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
854 m_execInterface.notifyOfExternalEvent();
857 case FieldDescriptor::TYPE_FIXED32:
858 case FieldDescriptor::TYPE_UINT32:
859 if (value.valueType() != PLEXIL::INTEGER_TYPE) {
860 warn(
"ProtobufCommAdapter:pb_set_value:" 861 "Invalid type for field " 862 << field_name <<
", expects Integer, got " 863 << PLEXIL::valueTypeName(value.valueType()));
864 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
865 m_execInterface.notifyOfExternalEvent();
870 if (field->is_repeated()) {
872 refl->AddUInt32(msg, field, v);
874 refl->SetRepeatedUInt32(msg, field, partial_index, v);
877 refl->SetUInt32(msg, field, v);
882 case FieldDescriptor::TYPE_ENUM:
883 if (value.valueType() != PLEXIL::STRING_TYPE) {
884 warn(
"ProtobufCommAdapter:pb_set_value:" 885 "Invalid type for field " 886 << field_name <<
", expects String, got " << PLEXIL::valueTypeName(value.valueType()));
887 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
888 m_execInterface.notifyOfExternalEvent();
894 const EnumDescriptor * enumdesc = field->enum_type();
895 const EnumValueDescriptor *enumval = enumdesc->FindValueByName(v);
897 if (field->is_repeated()) {
899 refl->AddEnum(msg, field, enumval);
901 refl->SetRepeatedEnum(msg, field, partial_index, enumval);
904 refl->SetEnum(msg, field, enumval);
907 warn(
"ProtobufCommAdapter:pb_set_value:" 908 "Invalid enum value '" 909 << v <<
"' for field " << field_name);
910 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
911 m_execInterface.notifyOfExternalEvent();
918 }
catch (std::logic_error &e) {
919 warn(
"ProtobufCommAdapter:pb_set_value:" 920 "Failed to set field " 921 << field_name <<
": " << e.what());
922 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
923 m_execInterface.notifyOfExternalEvent();
926 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
927 m_execInterface.notifyOfExternalEvent();
931 ProtobufCommPlexilAdapter::pb_get_value(PLEXIL::Command *cmd, PLEXIL::ValueType value_type)
933 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
934 if (!verify_args(args,
935 "ProtobufCommAdapter:pb_get_value",
936 {{
"msg_id", PLEXIL::STRING_TYPE}, {
"field", PLEXIL::STRING_TYPE}})) {
937 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
938 m_execInterface.notifyOfExternalEvent();
943 std::string field_name;
944 args[0].getValue(msg_id);
945 args[1].getValue(field_name);
947 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
949 warn(
"ProtobufCommAdapter:pb_get_value:" 950 <<
" Unknown message " << msg_id);
951 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
952 m_execInterface.notifyOfExternalEvent();
956 const FieldDescriptor * field =
nullptr;
957 google::protobuf::Message *msg = m.get();
959 std::string partial_name;
960 long int partial_index = -1;
962 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_get_value")) {
963 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
964 m_execInterface.notifyOfExternalEvent();
969 warn(
"ProtobufCommAdapter:pb_get_value:" 970 <<
" Unknown field " << field_name <<
" for message " << msg_id);
971 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
972 m_execInterface.notifyOfExternalEvent();
976 if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
977 warn(
"ProtobufCommAdapter:pb_get_value:" 978 <<
" Final sub-field " << field_name <<
" is a message");
979 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
980 m_execInterface.notifyOfExternalEvent();
984 const Reflection *refl = msg->GetReflection();
987 switch (field->type()) {
988 case FieldDescriptor::TYPE_DOUBLE:
989 case FieldDescriptor::TYPE_FLOAT:
990 if (value_type != PLEXIL::REAL_TYPE) {
991 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
992 <<
" not of expected type Real");
993 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
994 m_execInterface.notifyOfExternalEvent();
999 case FieldDescriptor::TYPE_INT64:
1000 case FieldDescriptor::TYPE_SFIXED64:
1001 case FieldDescriptor::TYPE_SINT64:
1002 case FieldDescriptor::TYPE_UINT64:
1003 case FieldDescriptor::TYPE_FIXED64:
1004 case FieldDescriptor::TYPE_INT32:
1005 case FieldDescriptor::TYPE_SFIXED32:
1006 case FieldDescriptor::TYPE_SINT32:
1007 case FieldDescriptor::TYPE_UINT32:
1008 case FieldDescriptor::TYPE_FIXED32:
1009 if (value_type != PLEXIL::INTEGER_TYPE) {
1010 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1011 <<
" not of expected type Integer");
1012 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1013 m_execInterface.notifyOfExternalEvent();
1018 case FieldDescriptor::TYPE_BOOL:
1019 if (value_type != PLEXIL::BOOLEAN_TYPE) {
1020 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1021 <<
" not of expected type Boolean");
1022 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1023 m_execInterface.notifyOfExternalEvent();
1028 case FieldDescriptor::TYPE_STRING:
1029 case FieldDescriptor::TYPE_ENUM:
1030 if (value_type != PLEXIL::STRING_TYPE) {
1031 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1032 <<
" not of expected type String");
1033 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1034 m_execInterface.notifyOfExternalEvent();
1040 if (value_type != PLEXIL::STRING_TYPE) {
1041 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1042 <<
" of unsupported protobuf type");
1043 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1044 m_execInterface.notifyOfExternalEvent();
1050 if (field->is_repeated()) {
1051 if (partial_index >= refl->FieldSize(*msg, field)) {
1052 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
"Index " << partial_index
1053 <<
" for " << partial_name <<
" is out of bounds");
1054 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1055 m_execInterface.notifyOfExternalEvent();
1059 switch (field->type()) {
1060 case FieldDescriptor::TYPE_DOUBLE:
1061 m_execInterface.handleCommandReturn(cmd,
1063 refl->GetRepeatedDouble(*msg, field, partial_index)));
1065 case FieldDescriptor::TYPE_FLOAT:
1066 m_execInterface.handleCommandReturn(cmd,
1068 refl->GetRepeatedFloat(*msg, field, partial_index)));
1070 case FieldDescriptor::TYPE_UINT64:
1071 case FieldDescriptor::TYPE_FIXED64:
1072 m_execInterface.handleCommandReturn(
1073 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedUInt64(*msg, field, partial_index)));
1075 case FieldDescriptor::TYPE_UINT32:
1076 case FieldDescriptor::TYPE_FIXED32:
1077 m_execInterface.handleCommandReturn(
1078 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedUInt32(*msg, field, partial_index)));
1080 case FieldDescriptor::TYPE_BOOL:
1081 m_execInterface.handleCommandReturn(
1082 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedBool(*msg, field, partial_index)));
1084 case FieldDescriptor::TYPE_STRING:
1085 m_execInterface.handleCommandReturn(cmd,
1087 refl->GetRepeatedString(*msg, field, partial_index)));
1089 case FieldDescriptor::TYPE_ENUM:
1090 m_execInterface.handleCommandReturn(
1091 cmd, PLEXIL::Value(refl->GetRepeatedEnum(*msg, field, partial_index)->name()));
1093 case FieldDescriptor::TYPE_SFIXED32:
1094 case FieldDescriptor::TYPE_INT32:
1095 case FieldDescriptor::TYPE_SINT32:
1096 m_execInterface.handleCommandReturn(
1097 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedInt32(*msg, field, partial_index)));
1099 case FieldDescriptor::TYPE_SFIXED64:
1100 case FieldDescriptor::TYPE_SINT64:
1101 case FieldDescriptor::TYPE_INT64:
1102 m_execInterface.handleCommandReturn(
1103 cmd, PLEXIL::Value((PLEXIL::Integer)refl->GetRepeatedInt64(*msg, field, partial_index)));
1109 if (!refl->HasField(*msg, field)) {
1110 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
":" << field_name
1112 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1113 m_execInterface.notifyOfExternalEvent();
1118 switch (field->type()) {
1119 case FieldDescriptor::TYPE_DOUBLE:
1120 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetDouble(*msg, field)));
1122 case FieldDescriptor::TYPE_FLOAT:
1123 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetFloat(*msg, field)));
1125 case FieldDescriptor::TYPE_INT64:
1126 case FieldDescriptor::TYPE_SFIXED64:
1127 case FieldDescriptor::TYPE_SINT64:
1128 m_execInterface.handleCommandReturn(cmd,
1130 (PLEXIL::Integer)refl->GetInt64(*msg, field)));
1132 case FieldDescriptor::TYPE_UINT64:
1133 case FieldDescriptor::TYPE_FIXED64:
1134 m_execInterface.handleCommandReturn(cmd,
1136 (PLEXIL::Integer)refl->GetUInt64(*msg, field)));
1138 case FieldDescriptor::TYPE_INT32:
1139 case FieldDescriptor::TYPE_SFIXED32:
1140 case FieldDescriptor::TYPE_SINT32:
1141 m_execInterface.handleCommandReturn(cmd,
1143 (PLEXIL::Integer)refl->GetInt32(*msg, field)));
1145 case FieldDescriptor::TYPE_UINT32:
1146 case FieldDescriptor::TYPE_FIXED32:
1147 m_execInterface.handleCommandReturn(cmd,
1149 (PLEXIL::Integer)refl->GetUInt32(*msg, field)));
1151 case FieldDescriptor::TYPE_BOOL:
1152 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetBool(*msg, field)));
1154 case FieldDescriptor::TYPE_STRING:
1155 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetString(*msg, field)));
1158 case FieldDescriptor::TYPE_ENUM:
1159 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->GetEnum(*msg, field)->name()));
1163 warn(
"ProtobufCommAdapter:pb_get_value:" << m->GetTypeName() <<
" invalid value type for " 1165 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1166 m_execInterface.notifyOfExternalEvent();
1171 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1172 m_execInterface.notifyOfExternalEvent();
1176 ProtobufCommPlexilAdapter::pb_get_length(PLEXIL::Command *cmd)
1178 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1179 if (!verify_args(args,
1180 "ProtobufCommAdapter:pb_get_length",
1181 {{
"msg_id", PLEXIL::STRING_TYPE}, {
"field", PLEXIL::STRING_TYPE}})) {
1182 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1183 m_execInterface.notifyOfExternalEvent();
1188 std::string field_name;
1189 args[0].getValue(msg_id);
1190 args[1].getValue(field_name);
1192 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1194 warn(
"ProtobufCommAdapter:pb_get_length:" 1195 <<
" Unknown message " << msg_id);
1196 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1197 m_execInterface.notifyOfExternalEvent();
1201 const FieldDescriptor * field =
nullptr;
1202 google::protobuf::Message *msg = m.get();
1204 std::string partial_name;
1205 long int partial_index = -1;
1207 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_get_length")) {
1208 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1209 m_execInterface.notifyOfExternalEvent();
1214 warn(
"ProtobufCommAdapter:pb_get_length:" 1215 <<
" Unknown field " << field_name <<
" for message " << msg_id);
1216 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1217 m_execInterface.notifyOfExternalEvent();
1221 if (!field->is_repeated()) {
1222 warn(
"ProtobufCommAdapter:pb_get_length:" 1223 <<
" Field " << field_name <<
" is not a repeated field in " << msg_id);
1224 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1225 m_execInterface.notifyOfExternalEvent();
1228 const Reflection *refl = msg->GetReflection();
1230 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->FieldSize(*msg, field)));
1231 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1232 m_execInterface.notifyOfExternalEvent();
1236 ProtobufCommPlexilAdapter::pb_has_field(PLEXIL::Command *cmd)
1238 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1239 if (!verify_args(args,
1240 "ProtobufCommAdapter:pb_has_field",
1241 {{
"msg_id", PLEXIL::STRING_TYPE}, {
"field", PLEXIL::STRING_TYPE}})) {
1242 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1243 m_execInterface.notifyOfExternalEvent();
1248 std::string field_name;
1249 args[0].getValue(msg_id);
1250 args[1].getValue(field_name);
1252 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1254 warn(
"ProtobufCommAdapter:pb_has_field:" 1255 <<
" Unknown message " << msg_id);
1256 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1257 m_execInterface.notifyOfExternalEvent();
1261 const FieldDescriptor * field =
nullptr;
1262 google::protobuf::Message *msg = m.get();
1264 std::string partial_name;
1265 long int partial_index = -1;
1267 if (!traverse_field(msg, field_name, field, partial_name, partial_index,
"pb_has_field")) {
1268 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(
false));
1269 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1270 m_execInterface.notifyOfExternalEvent();
1275 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(
false));
1276 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1277 m_execInterface.notifyOfExternalEvent();
1281 const Reflection *refl = msg->GetReflection();
1283 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(refl->HasField(*msg, field)));
1284 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1285 m_execInterface.notifyOfExternalEvent();
1289 ProtobufCommPlexilAdapter::pb_tostring(PLEXIL::Command *cmd)
1291 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1292 if (!verify_args(args,
"ProtobufCommAdapter:pb_tostring", {{
"msg_id", PLEXIL::STRING_TYPE}})) {
1293 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1294 m_execInterface.notifyOfExternalEvent();
1299 args[0].getValue(msg_id);
1301 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1303 warn(
"ProtobufCommAdapter:pb_tostring:" 1304 <<
" Unknown message " << msg_id);
1305 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1306 m_execInterface.notifyOfExternalEvent();
1310 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(m->DebugString()));
1311 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1312 m_execInterface.notifyOfExternalEvent();
1316 ProtobufCommPlexilAdapter::pb_broadcast(PLEXIL::Command *cmd)
1318 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1319 if (!verify_args(args,
1320 "ProtobufCommAdapter:pb_broadcast",
1321 {{
"peer_id", PLEXIL::INTEGER_TYPE}, {
"msg_id", PLEXIL::STRING_TYPE}})) {
1322 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1323 m_execInterface.notifyOfExternalEvent();
1329 args[0].getValue(peer_id);
1330 args[1].getValue(msg_id);
1332 if (peers_.find(peer_id) == peers_.end()) {
1333 warn(
"ProtobufCommAdapter:pb_broadcast:" 1334 <<
" Unknown peer " << peer_id);
1335 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1336 m_execInterface.notifyOfExternalEvent();
1340 std::shared_ptr<google::protobuf::Message> m = get_message(msg_id);
1342 warn(
"ProtobufCommAdapter:pb_broadcast:" 1343 <<
" Unknown message " << msg_id);
1344 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1345 m_execInterface.notifyOfExternalEvent();
1349 std::lock_guard<std::mutex> lock(map_mutex_);
1353 peers_[peer_id]->send(m);
1354 }
catch (google::protobuf::FatalException &e) {
1355 warn(
"ProtobufCommAdapter:pb_broadcast:" 1356 <<
" Failed to send message " << msg_id <<
"(" << e.what() <<
")");
1357 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1358 m_execInterface.notifyOfExternalEvent();
1361 warn(
"ProtobufCommAdapter:pb_broadcast:" 1362 <<
" Failed to send message " << msg_id <<
"(" << e.
what_no_backtrace() <<
")");
1363 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1364 m_execInterface.notifyOfExternalEvent();
1366 }
catch (std::runtime_error &e) {
1367 warn(
"ProtobufCommAdapter:pb_broadcast:" 1368 <<
" Failed to message " << msg_id <<
"(" << e.what() <<
")");
1369 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1370 m_execInterface.notifyOfExternalEvent();
1375 std::lock_guard<std::mutex> lock(queue_mutex_);
1376 messages_.erase(msg_id);
1379 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1380 m_execInterface.notifyOfExternalEvent();
1392 ProtobufCommPlexilAdapter::pb_peer_create_local_crypto(
1393 PLEXIL::Command * cmd,
1394 const std::vector<PLEXIL::Value> *override_args)
1396 std::vector<PLEXIL::Value>
const &args = override_args ? *override_args : cmd->getArgValues();
1398 if (!verify_args(args,
1399 "ProtobufCommAdapter:pb_peer_create_local_crypto",
1400 {{
"address", PLEXIL::STRING_TYPE},
1401 {
"send_port", PLEXIL::INTEGER_TYPE},
1402 {
"recv_port", PLEXIL::INTEGER_TYPE},
1403 {
"crypto_key", PLEXIL::STRING_TYPE},
1404 {
"cipher", PLEXIL::STRING_TYPE}})) {
1405 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1406 m_execInterface.notifyOfExternalEvent();
1410 std::string address;
1411 int send_port, recv_port;
1412 std::string crypto_key, cipher;
1414 args[0].getValue(address);
1415 args[1].getValue(send_port);
1416 args[2].getValue(recv_port);
1417 args[3].getValue(crypto_key);
1418 args[4].getValue(cipher);
1421 recv_port = send_port;
1423 if (send_port > 0) {
1424 std::shared_ptr<ProtobufBroadcastPeer> peer =
1425 std::make_shared<ProtobufBroadcastPeer>(address,
1426 (
unsigned short)send_port,
1427 (
unsigned short)recv_port,
1428 &*message_register_,
1434 std::lock_guard<std::mutex> lock(map_mutex_);
1435 peer_id = ++next_client_id_;
1436 peers_[peer_id] = peer;
1440 boost::bind(&ProtobufCommPlexilAdapter::handle_peer_msg,
this, peer_id, _1, _2, _3, _4));
1442 boost::bind(&ProtobufCommPlexilAdapter::handle_peer_recv_error,
this, peer_id, _1, _2));
1444 boost::bind(&ProtobufCommPlexilAdapter::handle_peer_send_error,
this, peer_id, _1));
1446 m_execInterface.handleCommandReturn(cmd, PLEXIL::Value(peer_id));
1447 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1448 m_execInterface.notifyOfExternalEvent();
1450 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1451 m_execInterface.notifyOfExternalEvent();
1463 ProtobufCommPlexilAdapter::pb_peer_create_crypto(PLEXIL::Command *cmd)
1465 std::vector<PLEXIL::Value>
const &in_args = cmd->getArgValues();
1466 if (!verify_args(in_args,
1467 "pb_peer_create_crypto",
1468 {{
"address", PLEXIL::STRING_TYPE},
1469 {
"port", PLEXIL::INTEGER_TYPE},
1470 {
"crypto_key", PLEXIL::STRING_TYPE},
1471 {
"cipher", PLEXIL::STRING_TYPE}})) {
1472 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1473 m_execInterface.notifyOfExternalEvent();
1477 std::vector<PLEXIL::Value> args{in_args[0], in_args[1], in_args[1], in_args[2], in_args[3]};
1479 pb_peer_create_local_crypto(cmd, &args);
1488 ProtobufCommPlexilAdapter::pb_peer_create(PLEXIL::Command *cmd)
1490 std::vector<PLEXIL::Value>
const &in_args = cmd->getArgValues();
1491 if (!verify_args(in_args,
1493 {{
"address", PLEXIL::STRING_TYPE}, {
"port", PLEXIL::INTEGER_TYPE}})) {
1494 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1495 m_execInterface.notifyOfExternalEvent();
1499 std::vector<PLEXIL::Value> args{
1500 in_args[0], in_args[1], in_args[1], PLEXIL::Value(
""), PLEXIL::Value(
"")};
1502 pb_peer_create_local_crypto(cmd, &args);
1512 ProtobufCommPlexilAdapter::pb_peer_create_local(PLEXIL::Command *cmd)
1514 std::vector<PLEXIL::Value>
const &in_args = cmd->getArgValues();
1515 if (!verify_args(in_args,
1516 "pb_peer_create_local",
1517 {{
"address", PLEXIL::STRING_TYPE},
1518 {
"send_port", PLEXIL::INTEGER_TYPE},
1519 {
"recv_port", PLEXIL::INTEGER_TYPE}})) {
1520 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1521 m_execInterface.notifyOfExternalEvent();
1525 std::vector<PLEXIL::Value> args{
1526 in_args[0], in_args[1], in_args[2], PLEXIL::Value(
""), PLEXIL::Value(
"")};
1528 pb_peer_create_local_crypto(cmd, &args);
1535 ProtobufCommPlexilAdapter::pb_peer_destroy(PLEXIL::Command *cmd)
1537 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1538 if (!verify_args(args,
1539 "ProtobufCommAdapter:pb_peer_destroy",
1540 {{
"peer_id", PLEXIL::INTEGER_TYPE}})) {
1541 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1542 m_execInterface.notifyOfExternalEvent();
1547 args[0].getValue(peer_id);
1549 peers_.erase(peer_id);
1551 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1552 m_execInterface.notifyOfExternalEvent();
1561 ProtobufCommPlexilAdapter::pb_peer_setup_crypto(PLEXIL::Command *cmd)
1563 std::vector<PLEXIL::Value>
const &args = cmd->getArgValues();
1564 if (!verify_args(args,
1565 "ProtobufCommAdapter:pb_peer_setup_crypto",
1566 {{
"peer_id", PLEXIL::INTEGER_TYPE},
1567 {
"crypto_key", PLEXIL::STRING_TYPE},
1568 {
"cipher", PLEXIL::STRING_TYPE}})) {
1569 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_FAILED);
1570 m_execInterface.notifyOfExternalEvent();
1575 std::string crypto_key;
1578 args[0].getValue(peer_id);
1579 args[1].getValue(crypto_key);
1580 args[2].getValue(cipher);
1582 if (peers_.find(peer_id) != peers_.end()) {
1583 peers_[peer_id]->setup_crypto(crypto_key, cipher);
1586 m_execInterface.handleCommandAck(cmd, PLEXIL::COMMAND_SUCCESS);
1587 m_execInterface.notifyOfExternalEvent();
1597 ProtobufCommPlexilAdapter::handle_peer_msg(
int peer_id,
1598 boost::asio::ip::udp::endpoint & endpoint,
1599 uint16_t component_id,
1601 std::shared_ptr<google::protobuf::Message> msg)
1604 .from_host = endpoint.address().to_string(),
1605 .from_port = endpoint.port(),
1608 add_message(msg->GetTypeName(), std::move(m));
1609 proc_queue(msg->GetTypeName());
1617 ProtobufCommPlexilAdapter::handle_peer_recv_error(
int peer_id,
1618 boost::asio::ip::udp::endpoint &endpoint,
1622 logger_->
log_warn(
"PlexilProtobuf",
1623 "Failed to receive peer message from %s:%u: %s",
1624 endpoint.address().to_string().c_str(),
1634 ProtobufCommPlexilAdapter::handle_peer_send_error(
int peer_id, std::string msg)
1637 logger_->
log_warn(
"PlexilProtobuf",
"Failed to send peer message: %s", msg.c_str());
1643 initProtobufCommAdapter()
virtual bool start()
Start adapter.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
ProtobufCommPlexilAdapter(PLEXIL::AdapterExecInterface &execInterface)
Constructor.
virtual bool initialize()
Initialize adapter.
Fawkes library namespace.
virtual bool reset()
Reset adapter.
void executeCommand(PLEXIL::Command *cmd)
Perform given command.
virtual bool shutdown()
Shut adapter down.
A class for handling time.
virtual ~ProtobufCommPlexilAdapter()
Destructor.
signal_send_error_type & signal_send_error()
Signal that is invoked when sending a message failed.
Base class for exceptions in Fawkes.
signal_received_type & signal_received()
Signal that is invoked when a message has been received.
Interface adapter to provide logging facilities.
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
void invokeAbort(PLEXIL::Command *cmd)
Abort currently running execution.
signal_recv_error_type & signal_recv_error()
Signal that is invoked when receiving a message failed.
virtual bool stop()
Stop adapter.