blob: 515da71d8a35ea752d160e36bb72e461760294a8 [file] [log] [blame]
Eric Schmiedeberg7055b7e2022-07-19 10:04:58 -06001#include <poll.h>
Brian Silvermanea2c95f2021-02-10 18:10:26 -08002#include <unistd.h>
3
4#include <iostream>
5
6#include "aos/aos_cli_utils.h"
7#include "aos/configuration.h"
8#include "aos/init.h"
9#include "aos/json_to_flatbuffer.h"
10#include "gflags/gflags.h"
11#include "glog/logging.h"
12
James Kuszmaul27ff5ac2022-01-21 11:43:48 -080013DEFINE_double(rate, -1, "Rate at which to send the message (-1 to send once).");
14
Brian Silvermanea2c95f2021-02-10 18:10:26 -080015int main(int argc, char **argv) {
16 gflags::SetUsageMessage(
17 "Sends messages on arbitrary channels.\n"
18 "Typical Usage: aos_send [--config path_to_config.json]"
19 " channel_name message_type '{\"foo\": \"bar\"}'\n"
20 "Example usage: aos_send /test aos.examples.Ping "
Eric Schmiedeberg7055b7e2022-07-19 10:04:58 -060021 "'{\"value\": 1}'\n"
22 "Pipe usage: cat ping.json | aos_send /test/ aos.examples.Ping -");
Brian Silvermanea2c95f2021-02-10 18:10:26 -080023 aos::InitGoogle(&argc, &argv);
24
25 aos::CliUtilInfo cli_info;
Austin Schuh59f3b0f2021-07-31 20:50:40 -070026 if (cli_info.Initialize(
27 &argc, &argv,
28 [&cli_info](const aos::Channel *channel) {
29 return aos::configuration::ChannelIsSendableOnNode(
30 channel, cli_info.event_loop->node());
31 },
32 false)) {
Brian Silvermanea2c95f2021-02-10 18:10:26 -080033 return 0;
34 }
35 if (cli_info.found_channels.size() > 1) {
36 LOG(FATAL) << "Matched multiple channels, but may only send on 1";
37 }
38
39 if (argc == 1) {
40 LOG(FATAL) << "Must specify a message to send";
41 }
42
Eric Schmiedeberg7055b7e2022-07-19 10:04:58 -060043 // Check if the user wants to use stdin (denoted by '-') or the argument
44 // present in argv for the message to send. CliUtilInfo will ensure the
45 // message data will be in argv[1]
46 std::string_view message_to_send{argv[1]};
47 std::string stdin_data;
48 if (message_to_send == "-") {
49 // Read in everything from stdin, blocks when there's no data on stdin
50 stdin_data = std::string(std::istreambuf_iterator(std::cin), {});
51 message_to_send = stdin_data;
52 }
53
Brian Silvermanea2c95f2021-02-10 18:10:26 -080054 const aos::Channel *const channel = cli_info.found_channels[0];
55 const std::unique_ptr<aos::RawSender> sender =
56 cli_info.event_loop->MakeRawSender(channel);
57 flatbuffers::FlatBufferBuilder fbb(sender->fbb_allocator()->size(),
58 sender->fbb_allocator());
Austin Schuha36cfa82021-03-20 21:56:03 -070059 fbb.ForceDefaults(true);
Eric Schmiedeberg7055b7e2022-07-19 10:04:58 -060060 fbb.Finish(aos::JsonToFlatbuffer(message_to_send, channel->schema(), &fbb));
James Kuszmaul27ff5ac2022-01-21 11:43:48 -080061
62 if (FLAGS_rate < 0) {
63 sender->CheckOk(sender->Send(fbb.GetSize()));
64 } else {
65 cli_info.event_loop
66 ->AddTimer([&fbb, &sender]() {
67 sender->CheckOk(sender->Send(fbb.GetBufferPointer(), fbb.GetSize()));
68 })
69 ->Setup(cli_info.event_loop->monotonic_now(),
70 std::chrono::duration_cast<std::chrono::nanoseconds>(
71 std::chrono::duration<double>(1.0 / FLAGS_rate)));
72 cli_info.event_loop->Run();
73 }
Brian Silvermanea2c95f2021-02-10 18:10:26 -080074
75 return 0;
76}