test_file_server.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #include <iostream>
  5. #include <string>
  6. #include <cstdlib>
  7. #include <cstdio>
  8. #include <sys/types.h>
  9. #include <unistd.h>
  10. #include "debug.hpp"
  11. // UAVCAN
  12. #include <uavcan/protocol/file_server.hpp>
  13. // UAVCAN Linux drivers
  14. #include <uavcan_linux/uavcan_linux.hpp>
  15. // UAVCAN POSIX drivers
  16. #include <uavcan_posix/basic_file_server_backend.hpp>
  17. #include <uavcan_posix/firmware_version_checker.hpp> // Compilability test
  18. namespace
  19. {
  20. uavcan_linux::NodePtr initNode(const std::vector<std::string>& ifaces, uavcan::NodeID nid, const std::string& name)
  21. {
  22. auto node = uavcan_linux::makeNode(ifaces);
  23. node->setNodeID(nid);
  24. node->setName(name.c_str());
  25. node->getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
  26. {
  27. const auto app_id = uavcan_linux::makeApplicationID(uavcan_linux::MachineIDReader().read(), name, nid.get());
  28. uavcan::protocol::HardwareVersion hwver;
  29. std::copy(app_id.begin(), app_id.end(), hwver.unique_id.begin());
  30. std::cout << hwver << std::endl;
  31. node->setHardwareVersion(hwver);
  32. }
  33. const int start_res = node->start();
  34. ENFORCE(0 == start_res);
  35. node->setModeOperational();
  36. return node;
  37. }
  38. void runForever(const uavcan_linux::NodePtr& node)
  39. {
  40. uavcan_posix::BasicFileServerBackend backend(*node);
  41. uavcan::FileServer server(*node, backend);
  42. const int server_init_res = server.start();
  43. if (server_init_res < 0)
  44. {
  45. throw std::runtime_error("Failed to start the server; error " + std::to_string(server_init_res));
  46. }
  47. while (true)
  48. {
  49. const int res = node->spin(uavcan::MonotonicDuration::fromMSec(100));
  50. if (res < 0)
  51. {
  52. std::cerr << "Spin error: " << res << std::endl;
  53. }
  54. }
  55. }
  56. struct Options
  57. {
  58. uavcan::NodeID node_id;
  59. std::vector<std::string> ifaces;
  60. };
  61. Options parseOptions(int argc, const char** argv)
  62. {
  63. const char* const executable_name = *argv++;
  64. argc--;
  65. const auto enforce = [executable_name](bool condition, const char* error_text) {
  66. if (!condition)
  67. {
  68. std::cerr << error_text << "\n"
  69. << "Usage:\n\t"
  70. << executable_name
  71. << " <node-id> <can-iface-name-1> [can-iface-name-N...]"
  72. << std::endl;
  73. std::exit(1);
  74. }
  75. };
  76. enforce(argc >= 2, "Not enough arguments");
  77. /*
  78. * Node ID is always at the first position
  79. */
  80. argc--;
  81. const int node_id = std::stoi(*argv++);
  82. enforce(node_id >= 1 && node_id <= 127, "Invalid node ID");
  83. Options out;
  84. out.node_id = uavcan::NodeID(std::uint8_t(node_id));
  85. while (argc --> 0)
  86. {
  87. const std::string token(*argv++);
  88. if (token[0] != '-')
  89. {
  90. out.ifaces.push_back(token);
  91. }
  92. else
  93. {
  94. enforce(false, "Unexpected argument");
  95. }
  96. }
  97. return out;
  98. }
  99. }
  100. int main(int argc, const char** argv)
  101. {
  102. try
  103. {
  104. auto options = parseOptions(argc, argv);
  105. std::cout << "Self node ID: " << int(options.node_id.get()) << "\n"
  106. "Num ifaces: " << options.ifaces.size() << "\n"
  107. #ifdef NDEBUG
  108. "Build mode: Release"
  109. #else
  110. "Build mode: Debug"
  111. #endif
  112. << std::endl;
  113. auto node = initNode(options.ifaces, options.node_id, "org.uavcan.linux_test_file_server");
  114. runForever(node);
  115. return 0;
  116. }
  117. catch (const std::exception& ex)
  118. {
  119. std::cerr << "Error: " << ex.what() << std::endl;
  120. return 1;
  121. }
  122. }