HDLCd-Tools
main-hdlcd-hexinjector.cpp
Go to the documentation of this file.
1 
22 #include "Config.h"
23 #include <iostream>
24 #include <vector>
25 #include <list>
26 #include <boost/asio.hpp>
27 #include <boost/program_options.hpp>
28 #include <boost/regex.hpp>
29 #include "HdlcdClient.h"
30 
32 public:
33  // DTOR
35  Stop();
36  }
37 
38  void RegisterStopperCallback(std::function<void()> a_StopperCallback) {
39  m_StopperCallbackList.push_back(a_StopperCallback);
40  }
41 
42  void Stop() {
43  while (!m_StopperCallbackList.empty()) {
44  auto l_StopperCallback = m_StopperCallbackList.front();
45  m_StopperCallbackList.pop_front();
46  l_StopperCallback();
47  } // while
48  }
49 
50 private:
51  std::list<std::function<void()>> m_StopperCallbackList;
52 };
53 
54 int main(int argc, char* argv[]) {
55  try {
56  // Declare the supported options.
57  boost::program_options::options_description l_Description("Allowed options");
58  l_Description.add_options()
59  ("help,h", "produce this help message")
60  ("version,v", "show version information")
61  ("connect,c", boost::program_options::value<std::string>(),
62  "connect to a single device via the HDLCd\n"
63  "syntax: SerialPort@IPAddess:PortNbr\n"
64  " linux: /dev/ttyUSB0@localhost:5001\n"
65  " windows: //./COM1@example.com:5001")
66  ("payload,p", boost::program_options::value<std::string>(),
67  "quoted payload to be sent as hex dump")
68  ;
69 
70  // Parse the command line
71  boost::program_options::variables_map l_VariablesMap;
72  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, l_Description), l_VariablesMap);
73  boost::program_options::notify(l_VariablesMap);
74  if (l_VariablesMap.count("version")) {
75  std::cerr << "HDLCd payload injector (single packet as hexdump via command line) version " << HDLCD_TOOLS_VERSION_MAJOR << "." << HDLCD_TOOLS_VERSION_MINOR
76  << " built with hdlcd-devel version " << HDLCD_DEVEL_VERSION_MAJOR << "." << HDLCD_DEVEL_VERSION_MINOR << std::endl;
77  } // if
78 
79  if (l_VariablesMap.count("help")) {
80  std::cout << l_Description << std::endl;
81  std::cout << "The HDLC hex injector is Copyright (C) 2016, and GNU GPL'd, by Florian Evers." << std::endl;
82  std::cout << "Bug reports, feedback, admiration, abuse, etc, to: https://github.com/Strunzdesign/hdlcd-tools" << std::endl;
83  return 1;
84  } // if
85 
86  if (!l_VariablesMap.count("connect")) {
87  std::cout << "hdlcd-hexinjector: you have to specify one device to connect to" << std::endl;
88  std::cout << "hdlcd-hexinjector: Use --help for more information." << std::endl;
89  return 1;
90  } // if
91 
92  if (!l_VariablesMap.count("payload")) {
93  std::cout << "hdlcd-hexinjector: you have to provide a payload to be transmitted" << std::endl;
94  std::cout << "hdlcd-hexinjector: Use --help for more information." << std::endl;
95  return 1;
96  } // if
97 
98  // Initialize main components
99  boost::asio::io_service l_IoService;
100  SystemStopper l_SystemStopper;
101 
102  // Install signal handlers
103  boost::asio::signal_set l_Signals(l_IoService);
104  l_Signals.add(SIGINT);
105  l_Signals.add(SIGTERM);
106  l_Signals.async_wait([&l_SystemStopper](boost::system::error_code, int){ l_SystemStopper.Stop(); });
107  l_SystemStopper.RegisterStopperCallback([&l_Signals](){ l_Signals.cancel(); });
108 
109  // Parse the destination specifier
110  static boost::regex s_RegEx("^(.*?)@(.*?):(.*?)$");
111  boost::smatch l_Match;
112  if (boost::regex_match(l_VariablesMap["connect"].as<std::string>(), l_Match, s_RegEx)) {
113  // Resolve destination
114  boost::asio::ip::tcp::resolver l_Resolver(l_IoService);
115  auto l_EndpointIterator = l_Resolver.resolve({ l_Match[2], l_Match[3] });
116 
117  // Prepare the HDLCd client entity
118  HdlcdClient l_HdlcdClient(l_IoService, l_Match[1], HdlcdSessionDescriptor(SESSION_TYPE_TRX_ALL, SESSION_FLAGS_NONE));
119  l_HdlcdClient.SetOnClosedCallback([&l_SystemStopper](){ l_SystemStopper.Stop(); });
120  l_SystemStopper.RegisterStopperCallback([&l_HdlcdClient](){ l_HdlcdClient.Close(); });
121  l_HdlcdClient.AsyncConnect(l_EndpointIterator, [&l_VariablesMap, &l_HdlcdClient, &l_SystemStopper](bool a_bSuccess) {
122  if (a_bSuccess) {
123  // Prepare input
124  std::istringstream l_InputStream(l_VariablesMap["payload"].as<std::string>());
125  l_InputStream >> std::hex;
126  std::vector<unsigned char> l_Buffer;
127  l_Buffer.reserve(65536);
128  l_Buffer.insert(l_Buffer.end(),std::istream_iterator<unsigned int>(l_InputStream), {});
129  l_HdlcdClient.Send(std::move(HdlcdPacketData::CreatePacket(l_Buffer, true)));
130  l_HdlcdClient.Shutdown();
131  } else {
132  std::cout << "Failed to connect to the HDLC Daemon!" << std::endl;
133  l_SystemStopper.Stop();
134  } // else
135  }); // AsyncConnect
136 
137  // Start event processing
138  l_IoService.run();
139  } else {
140  throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
141  } // else
142  } catch (std::exception& a_Error) {
143  std::cerr << "Exception: " << a_Error.what() << "\n";
144  } // catch
145 
146  return 0;
147 }
#define HDLCD_DEVEL_VERSION_MINOR
Definition: HdlcdConfig.h:3
void AsyncConnect(boost::asio::ip::tcp::resolver::iterator a_EndpointIterator, std::function< void(bool a_bSuccess)> a_OnConnectedCallback)
Perform an asynchronous connect procedure regarding both TCP sockets.
Definition: HdlcdClient.h:82
bool Send(const HdlcdPacketData &a_PacketData, std::function< void()> a_OnSendDoneCallback=nullptr)
Send a single data packet to the peer entity.
Definition: HdlcdClient.h:203
#define HDLCD_DEVEL_VERSION_MAJOR
Definition: HdlcdConfig.h:2
static HdlcdPacketData CreatePacket(const std::vector< unsigned char > a_Payload, bool a_bReliable, bool a_bInvalid=false, bool a_bWasSent=false)
void Shutdown()
Shuts all TCP connections down.
Definition: HdlcdClient.h:127
void RegisterStopperCallback(std::function< void()> a_StopperCallback)
Class HdlcdClient.
Definition: HdlcdClient.h:54
void SetOnClosedCallback(std::function< void()> a_OnClosedCallback)
Provide a callback method to be called if this client entity is closing.
Definition: HdlcdClient.h:192
Copyright (c) 2016, Florian Evers, florian-evers@gmx.de All rights reserved.
int main(int argc, char *argv[])
void Close()
Close the client entity.
Definition: HdlcdClient.h:141