32 #include "goby/acomms/amac.h" 33 #include "goby/acomms/bind.h" 34 #include "goby/acomms/dccl.h" 35 #include "goby/acomms/modem_driver.h" 36 #include "goby/acomms/queue.h" 37 #include "goby/common/time.h" 38 #include "goby/util/as.h" 40 #include <boost/lexical_cast.hpp> 42 #include "chat_curses.h" 52 int startup_failure();
68 int main(
int argc,
char* argv[])
75 return startup_failure();
77 std::string serial_port = argv[1];
81 my_id_ = boost::lexical_cast<
int>(argv[2]);
82 buddy_id_ = boost::lexical_cast<
int>(argv[3]);
84 catch (boost::bad_lexical_cast&)
86 std::cerr <<
"bad value for my_id: " << argv[2] <<
" or buddy_id: " << argv[3]
87 <<
". these must be unsigned integers." << std::endl;
88 return startup_failure();
91 std::string log_file = argv[4];
92 fout_.open(log_file.c_str());
95 std::cerr <<
"bad value for log_file: " << log_file << std::endl;
96 return startup_failure();
106 bind(mm_driver_, q_manager_, mac_);
113 dccl_->validate<ChatMessage>();
119 q_manager_cfg.set_modem_id(my_id_);
121 q_entry->set_protobuf_name(
"ChatMessage");
123 #ifdef USE_FLEXIBLE_DATA_PACKET 124 q_entry->set_ack(
false);
128 src_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::SOURCE_ID);
129 src_role->set_field(
"source");
132 dest_role->set_type(goby::acomms::protobuf::QueuedMessageEntry::DESTINATION_ID);
133 dest_role->set_field(
"destination");
142 driver_cfg.set_modem_id(my_id_);
143 driver_cfg.set_serial_port(serial_port);
145 #ifdef USE_FLEXIBLE_DATA_PACKET 146 driver_cfg.AddExtension(micromodem::protobuf::Config::nvram_cfg,
147 "psk.packet.mod_hdr_version,1");
150 #ifdef USE_TWO_WAY_PING 158 mac_cfg.set_type(goby::acomms::protobuf::MAC_FIXED_DECENTRALIZED);
159 mac_cfg.set_modem_id(my_id_);
163 my_slot.set_src(my_id_);
164 my_slot.set_dest(buddy_id_);
165 #ifdef USE_FLEXIBLE_DATA_PACKET 166 my_slot.set_type(goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC);
167 my_slot.SetExtension(micromodem::protobuf::type,
168 micromodem::protobuf::MICROMODEM_FLEXIBLE_DATA);
169 my_slot.set_max_frame_bytes(32);
171 #elif defined(USE_TWO_WAY_PING) 172 my_slot.set_type(goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC);
173 my_slot.SetExtension(micromodem::protobuf::type, micromodem::protobuf::MICROMODEM_TWO_WAY_PING);
175 my_slot.set_type(goby::acomms::protobuf::ModemTransmission::DATA);
178 my_slot.set_slot_seconds(12);
181 buddy_slot.set_src(buddy_id_);
182 buddy_slot.set_dest(my_id_);
183 buddy_slot.set_slot_seconds(12);
184 #ifdef USE_FLEXIBLE_DATA_PACKET 185 buddy_slot.set_type(goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC);
186 buddy_slot.SetExtension(micromodem::protobuf::type,
187 micromodem::protobuf::MICROMODEM_FLEXIBLE_DATA);
188 buddy_slot.set_max_frame_bytes(32);
189 buddy_slot.set_rate(1);
190 #elif defined(USE_TWO_WAY_PING) 191 buddy_slot.set_type(goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC);
192 buddy_slot.SetExtension(micromodem::protobuf::type,
193 micromodem::protobuf::MICROMODEM_TWO_WAY_PING);
195 buddy_slot.set_type(goby::acomms::protobuf::ModemTransmission::DATA);
196 buddy_slot.set_rate(0);
199 if (my_id_ < buddy_id_)
201 mac_cfg.add_slot()->CopyFrom(my_slot);
202 mac_cfg.add_slot()->CopyFrom(buddy_slot);
206 mac_cfg.add_slot()->CopyFrom(buddy_slot);
207 mac_cfg.add_slot()->CopyFrom(my_slot);
215 dccl_->set_cfg(dccl_cfg);
216 q_manager_.
set_cfg(q_manager_cfg);
218 mm_driver_.
startup(driver_cfg);
220 catch (std::runtime_error& e)
222 std::cerr <<
"exception at startup: " << e.what() << std::endl;
223 return startup_failure();
239 ChatMessage message_out;
240 message_out.set_telegram(line);
243 message_out.set_destination(buddy_id_);
244 message_out.set_source(my_id_);
255 catch (std::runtime_error& e)
258 std::cerr <<
"exception while running: " << e.what() << std::endl;
266 int startup_failure()
268 std::cerr <<
"usage: chat /dev/tty_modem my_id buddy_id log_file" << std::endl;
274 if (mac_msg.src() == my_id_)
275 curses_.
post_message(
"{control} starting send to my buddy");
276 else if (mac_msg.src() == buddy_id_)
277 curses_.
post_message(
"{control} my buddy might be sending to me now");
282 if (rx_msg.GetExtension(micromodem::protobuf::type) ==
283 micromodem::protobuf::MICROMODEM_TWO_WAY_PING &&
284 rx_msg.HasExtension(micromodem::protobuf::ranging_reply))
287 rx_msg.GetExtension(micromodem::protobuf::ranging_reply);
288 if (range_reply.one_way_travel_time_size() > 0)
290 double owtt = range_reply.one_way_travel_time(0);
298 ChatMessage typed_message_in;
299 typed_message_in.CopyFrom(message_in);
300 curses_.
post_message(typed_message_in.source(), typed_message_in.telegram());
306 ChatMessage typed_original_message;
307 typed_original_message.CopyFrom(original_message);
310 std::string(
"{ acknowledged receiving message starting with: " +
311 typed_original_message.telegram().substr(0, 5) +
" }"));
provides an API to the goby-acomms Queuing Library.
boost::signals2::signal< void(const protobuf::ModemTransmission &ack_msg, const google::protobuf::Message &orig_msg)> signal_ack
Signals when acknowledgment of proper message receipt has been received. This is only sent for queues...
void set_name(const std::string &s)
Set the name of the application that the logger is serving.
void run_input(std::string &line)
grab a character and if there's a line to return it will be returned in line
static DCCLCodec * get()
DCCLCodec is a singleton class; use this to get a pointer to the class.
provides a terminal GUI for a chat window (lower box to type and upper box to receive messages)...
void startup(const protobuf::MACConfig &cfg)
Starts the MAC with given configuration.
boost::signals2::signal< void(const google::protobuf::Message &msg)> signal_receive
Signals when a DCCL message is received.
void startup()
start the display
void do_work()
Allows the MAC timer to do its work. Does not block. If you prefer more control you can directly cont...
provides an API to the WHOI Micro-Modem driver
ReturnType goby_time()
Returns current UTC time as a boost::posix_time::ptime.
boost::signals2::signal< void(const protobuf::ModemTransmission &message)> signal_receive
Called when a binary data transmission is received from the modem.
void post_message(unsigned id, const std::string &line)
add a message to the upper window (the chat log)
void do_work()
See ModemDriverBase::do_work()
provides an API to the goby-acomms MAC library. MACManager is essentially a std::list<protobuf::Modem...
void connect(Signal *signal, Slot slot)
connect a signal to a slot (e.g. function pointer)
common::FlexOstream glog
Access the Goby logger through this object.
void set_cfg(const protobuf::QueueManagerConfig &cfg)
Set (and overwrite completely if present) the current configuration. (protobuf::QueueManagerConfig de...
void startup(const protobuf::DriverConfig &cfg)
Starts the driver.
void do_work()
Calculates which messages have expired and emits the goby::acomms::QueueManager::signal_expire as nec...
void cleanup()
end the display
boost::signals2::signal< void(const protobuf::ModemTransmission &m)> signal_initiate_transmission
Signals when it is time for this platform to begin transmission of an acoustic message at the start o...
void add_stream(logger::Verbosity verbosity=logger::VERBOSE, std::ostream *os=0)
Attach a stream object (e.g. std::cout, std::ofstream, ...) to the logger with desired verbosity...
void bind(ModemDriverBase &driver, QueueManager &queue_manager)
binds the driver link-layer callbacks to the QueueManager
void push_message(const google::protobuf::Message &new_message)
Push a message (and add the queue if it does not exist)
void set_modem_id(unsigned id)
give the modem_id so we know how to label our messages