s-net-Tools
main-snet-streamtestclient.cpp
Go to the documentation of this file.
1 
22 #include "Config.h"
23 #include <assert.h>
24 #include <iostream>
25 #include <boost/asio.hpp>
26 #include <boost/program_options.hpp>
27 #include <boost/regex.hpp>
28 #include "HdlcdClient.h"
29 #include "StreamTestEntity.h"
30 
31 int main(int argc, char* argv[]) {
32  try {
33  // Declare the supported options.
34  boost::program_options::options_description l_Description("Allowed options");
35  l_Description.add_options()
36  ("help,h", "produce this help message")
37  ("version,v", "show version information")
38  ("connect,c", boost::program_options::value<std::string>(),
39  "syntax: SerialPort@IPAddess:PortNbr\n"
40  " linux: /dev/ttyUSB0@localhost:5001\n"
41  " windows: //./COM1@example.com:5001")
42  ("destination,d", boost::program_options::value<std::string>(),
43  "the destination address (SSA) as a 16bit hex value, e.g., as 0x3FF4 or as 3FF4")
44  ("source,s", boost::program_options::value<std::string>()->default_value("0x4000"),
45  "the OPTIONAL source address (SSA) as a 16bit hex value, e.g., as 0xFFFE or FFFE")
46  ;
47 
48  // Parse the command line
49  boost::program_options::variables_map l_VariablesMap;
50  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, l_Description), l_VariablesMap);
51  boost::program_options::notify(l_VariablesMap);
52  if (l_VariablesMap.count("version")) {
53  std::cerr << "s-net(r) stream test client version " << SNET_TOOLS_VERSION_MAJOR << "." << SNET_TOOLS_VERSION_MINOR
54  << " built with hdlcd-devel version " << HDLCD_DEVEL_VERSION_MAJOR << "." << HDLCD_DEVEL_VERSION_MINOR
55  << " and snet-devel version " << SNET_DEVEL_VERSION_MAJOR << "." << SNET_DEVEL_VERSION_MINOR << std::endl;
56  } // if
57 
58  if (l_VariablesMap.count("help")) {
59  std::cout << l_Description << std::endl;
60  std::cout << "The s-net(r) stream test client for the HDLC Daemon is Copyright (C) 2016, and GNU GPL'd, by Florian Evers." << std::endl;
61  std::cout << "Bug reports, feedback, admiration, abuse, etc, to: https://github.com/Strunzdesign/snet-tools" << std::endl;
62  return 1;
63  } // if
64 
65  if (!l_VariablesMap.count("connect")) {
66  std::cout << "snet-streamtestclient: you have to specify one device to connect to" << std::endl;
67  std::cout << "snet-streamtestclient: Use --help for more information." << std::endl;
68  return 1;
69  } // if
70 
71  uint16_t l_DstSSA = 0x3FF4;
72  if (!l_VariablesMap.count("destination")) {
73  std::cout << "snet-streamtestclient: you have to specify the destination address (SSA)" << std::endl;
74  std::cout << "snet-streamtestclient: Use --help for more information." << std::endl;
75  return 1;
76  } else {
77  // Convert the provided hexadecimal SSA
78  std::istringstream l_Converter(l_VariablesMap["destination"].as<std::string>());
79  l_Converter >> std::hex >> l_DstSSA;
80  } // else
81 
82  uint16_t l_SrcSSA;
83  if (!l_VariablesMap.count("source")) {
84  assert(false);
85  } else {
86  // Convert the provided hexadecimal SSA
87  std::istringstream l_Converter(l_VariablesMap["source"].as<std::string>());
88  l_Converter >> std::hex >> l_SrcSSA;
89  } // else
90 
91  // Install signal handlers
92  boost::asio::io_service l_IoService;
93  boost::asio::signal_set l_Signals(l_IoService);
94  l_Signals.add(SIGINT);
95  l_Signals.add(SIGTERM);
96  l_Signals.async_wait([&l_IoService](boost::system::error_code, int){ l_IoService.stop(); });
97 
98  // Parse the destination specifier
99  static boost::regex s_RegEx("^(.*?)@(.*?):(.*?)$");
100  boost::smatch l_Match;
101  if (boost::regex_match(l_VariablesMap["connect"].as<std::string>(), l_Match, s_RegEx)) {
102  // Resolve destination
103  boost::asio::ip::tcp::resolver l_Resolver(l_IoService);
104  auto l_EndpointIterator = l_Resolver.resolve({ l_Match[2], l_Match[3] });
105 
106  // Prepare the HDLCd client entity: 0x01 = Payload RX and TX, Ctrl RX and TX
107  HdlcdClient l_HdlcdClient(l_IoService, l_Match[1], HdlcdSessionDescriptor(SESSION_TYPE_TRX_ALL, SESSION_FLAGS_DELIVER_RCVD));
108  l_HdlcdClient.SetOnClosedCallback([&l_IoService](){ l_IoService.stop(); });
109 
110  // Prepare input then connect
111  StreamTestEntity l_StreamTestEntity(l_HdlcdClient, l_SrcSSA, l_DstSSA);
112  l_HdlcdClient.AsyncConnect(l_EndpointIterator, [&l_StreamTestEntity, &l_Signals](bool a_bSuccess) {
113  if (a_bSuccess) {
114  l_StreamTestEntity.Start();
115  } else {
116  std::cout << "Failed to connect to the HDLC Daemon!" << std::endl;
117  l_Signals.cancel();
118  } // else
119  }); // AsyncConnect
120 
121  // Start event processing
122  l_IoService.run();
123  } else {
124  throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
125  } // else
126  } catch (std::exception& a_Error) {
127  std::cerr << "Exception: " << a_Error.what() << "\n";
128  } // catch
129 
130  return 0;
131 }
int main(int argc, char *argv[])
#define HDLCD_DEVEL_VERSION_MINOR
Definition: HdlcdConfig.h:3
#define SNET_DEVEL_VERSION_MAJOR
Definition: SnetConfig.h:2
#define SNET_DEVEL_VERSION_MINOR
Definition: SnetConfig.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
#define HDLCD_DEVEL_VERSION_MAJOR
Definition: HdlcdConfig.h:2
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.
A set of tools to exchange and handle packets of s-net(r) devices via the HDLC Daemon. Copyright (C) 2016 Florian Evers, florian-evers@gmx.de.