Skip to content

Commit

Permalink
Merge pull request #24 from GobySoft/2.1-improve-iridium-driver
Browse files Browse the repository at this point in the history
2.1 improve iridium driver
  • Loading branch information
tsaubergine authored May 8, 2017
2 parents 007a4ba + f7ad945 commit 594c527
Show file tree
Hide file tree
Showing 14 changed files with 490 additions and 145 deletions.
48 changes: 27 additions & 21 deletions src/acomms/modemdriver/iridium_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ using goby::common::goby_time;
using goby::acomms::operator<<;


boost::shared_ptr<dccl::Codec> goby::acomms::iridium_header_dccl_;

goby::acomms::IridiumDriver::IridiumDriver()
: fsm_(driver_cfg_),
last_triple_plus_time_(0),
last_send_time_(0),
serial_fd_(-1),
next_frame_(0)
{

init_iridium_dccl();

// assert(byte_string_to_uint32(uint32_to_byte_string(16540)) == 16540);
}

Expand Down Expand Up @@ -190,8 +192,10 @@ void goby::acomms::IridiumDriver::process_transmission(protobuf::ModemTransmissi
{
signal_modify_transmission(&msg);

const static unsigned frame_max = IridiumHeader::descriptor()->FindFieldByName("frame_start")->options().GetExtension(dccl::field).max();

if(!msg.has_frame_start())
msg.set_frame_start(next_frame_);
msg.set_frame_start(next_frame_ % frame_max);

// set the frame size, if not set or if it exceeds the max configured
if(!msg.has_max_frame_bytes() || msg.max_frame_bytes() > driver_cfg_.GetExtension(IridiumDriverConfig::max_frame_size))
Expand All @@ -209,7 +213,8 @@ void goby::acomms::IridiumDriver::process_transmission(protobuf::ModemTransmissi
}
else if(msg.rate() == RATE_SBD)
{
fsm_.process_event(fsm::EvSBDBeginData()); // mailbox check
if(msg.GetExtension(IridiumDriverConfig::if_no_data_do_mailbox_check))
fsm_.process_event(fsm::EvSBDBeginData()); // mailbox check
}
}

Expand All @@ -221,26 +226,24 @@ void goby::acomms::IridiumDriver::do_work()
// display_state_cfg(&glog);
double now = goby_time<double>();

// if we're on a call, keep pushing data at the target rate
const double send_interval =
driver_cfg_.GetExtension(IridiumDriverConfig::max_frame_size) /
(driver_cfg_.GetExtension(IridiumDriverConfig::target_bit_rate) / static_cast<double>(BITS_IN_BYTE));


const fsm::OnCall* on_call = fsm_.state_cast<const fsm::OnCall*>();

if(fsm_.data_out().empty() &&
(now > (last_send_time_ + send_interval)))
{
if(on_call && !on_call->bye_sent())
{
process_transmission(rudics_mac_msg_, false);
last_send_time_ = now;
}
}

if(on_call)
{
// if we're on a call, keep pushing data at the target rate
const double send_wait =
on_call->last_bytes_sent() /
(driver_cfg_.GetExtension(IridiumDriverConfig::target_bit_rate) / static_cast<double>(BITS_IN_BYTE));

if(fsm_.data_out().empty() &&
(now > (on_call->last_tx_time() + send_wait)))
{
if(!on_call->bye_sent())
{
process_transmission(rudics_mac_msg_, false);
}
}

if(!on_call->bye_sent() &&
now > (on_call->last_tx_time() + driver_cfg_.GetExtension(IridiumDriverConfig::handshake_hangup_seconds)))
{
Expand Down Expand Up @@ -338,8 +341,11 @@ void goby::acomms::IridiumDriver::send(const protobuf::ModemTransmission& msg)
fsm_.buffer_data_out(msg);
else
{
std::string iridium_packet;
serialize_iridium_modem_message(&iridium_packet, msg);

std::string rudics_packet;
serialize_rudics_packet(msg.SerializeAsString(), &rudics_packet);
serialize_rudics_packet(iridium_packet, &rudics_packet);
fsm_.process_event(fsm::EvSBDBeginData(rudics_packet));
}

Expand Down
1 change: 0 additions & 1 deletion src/acomms/modemdriver/iridium_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ namespace goby
enum { TRIPLE_PLUS_WAIT = 2 };

protobuf::ModemTransmission rudics_mac_msg_;
double last_send_time_;


int serial_fd_;
Expand Down
87 changes: 83 additions & 4 deletions src/acomms/modemdriver/iridium_driver_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
#ifndef IridiumDriverCommon20150508H
#define IridiumDriverCommon20150508H

#include <dccl/field_codec_fixed.h>
#include <dccl/codec.h>
#include <dccl/field_codec_manager.h>

#include "goby/acomms/protobuf/iridium_driver.pb.h"

namespace goby
{
namespace acomms
Expand All @@ -36,13 +42,17 @@ namespace goby
: last_tx_time_(goby::common::goby_time<double>()),
last_rx_time_(0),
bye_received_(false),
bye_sent_(false)
bye_sent_(false),
total_bytes_sent_(0),
last_bytes_sent_(0)
{ }

double last_rx_tx_time() const { return std::max(last_tx_time_, last_rx_time_); }
double last_rx_time() const { return last_rx_time_; }
double last_tx_time() const { return last_tx_time_; }


int last_bytes_sent() const { return last_bytes_sent_; }
int total_bytes_sent() const { return total_bytes_sent_; }


void set_bye_received(bool b) { bye_received_ = b; }
void set_bye_sent(bool b) { bye_sent_ = b; }
Expand All @@ -53,13 +63,82 @@ namespace goby
void set_last_tx_time(double d) { last_tx_time_ = d; }
void set_last_rx_time(double d) { last_rx_time_ = d; }

void set_last_bytes_sent(int i)
{
last_bytes_sent_ = i;
total_bytes_sent_ += i;
}

private:
double last_tx_time_;
double last_rx_time_;
bool bye_received_;
bool bye_sent_;
bool bye_sent_;
int total_bytes_sent_;
int last_bytes_sent_;
};


// placeholder id codec that uses no bits, since we're always sending just this message on the wire
class IridiumHeaderIdentifierCodec : public dccl::TypedFixedFieldCodec<dccl::uint32>
{
dccl::Bitset encode() { return dccl::Bitset(); }
dccl::Bitset encode(const uint32& wire_value) { return dccl::Bitset(); }
dccl::uint32 decode(dccl::Bitset* bits) { return 0; }
virtual unsigned size() { return 0; }

};

extern boost::shared_ptr<dccl::Codec> iridium_header_dccl_;

inline void init_iridium_dccl()
{
dccl::FieldCodecManager::add<IridiumHeaderIdentifierCodec>("iridium_header_id");
iridium_header_dccl_.reset(new dccl::Codec("iridium_header_id"));
iridium_header_dccl_->load<IridiumHeader>();
}

inline void serialize_iridium_modem_message(std::string* out, const goby::acomms::protobuf::ModemTransmission& in)
{
IridiumHeader header;
header.set_src(in.src());
header.set_dest(in.dest());
if(in.has_rate())
header.set_rate(in.rate());
header.set_type(in.type());
if(in.has_ack_requested())
header.set_ack_requested(in.ack_requested());
if(in.has_frame_start())
header.set_frame_start(in.frame_start());
if(in.acked_frame_size())
header.set_acked_frame(in.acked_frame(0));

iridium_header_dccl_->encode(out, header);
if(in.frame_size())
*out += in.frame(0);
}

inline void parse_iridium_modem_message(std::string in, goby::acomms::protobuf::ModemTransmission* out)
{
IridiumHeader header;
iridium_header_dccl_->decode(&in, &header);

out->set_src(header.src());
out->set_dest(header.dest());
if(header.has_rate())
out->set_rate(header.rate());
out->set_type(header.type());
if(header.has_ack_requested())
out->set_ack_requested(header.ack_requested());
if(header.has_frame_start())
out->set_frame_start(header.frame_start());
if(header.has_acked_frame())
out->add_acked_frame(header.acked_frame());

if(in.size())
out->add_frame(in);
}

}
}

Expand Down
19 changes: 13 additions & 6 deletions src/acomms/modemdriver/iridium_driver_fsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "goby/common/logger.h"
#include "goby/common/time.h"
#include "goby/util/binary.h"
#include "goby/acomms/acomms_constants.h"

#include "rudics_packet.h"
#include "iridium_driver_fsm.h"
Expand Down Expand Up @@ -144,7 +145,7 @@ void goby::acomms::fsm::Command::handle_sbd_rx(const std::string& in)
std::string bytes;
parse_rudics_packet(&bytes, sbd_rx_data);
protobuf::ModemTransmission msg;
msg.ParseFromString(bytes);
parse_iridium_modem_message(bytes, &msg);
context< IridiumDriverFSM >().received().push_back(msg);
at_out().pop_front();

Expand Down Expand Up @@ -343,7 +344,7 @@ void goby::acomms::fsm::OnCall::in_state_react(const EvRxOnCallSerial& e)
parse_rudics_packet(&bytes, in);

protobuf::ModemTransmission msg;
msg.ParseFromString(bytes);
parse_iridium_modem_message(bytes, &msg);
context< IridiumDriverFSM >().received().push_back(msg);
set_last_rx_time(goby_time<double>());
}
Expand All @@ -357,21 +358,27 @@ void goby::acomms::fsm::OnCall::in_state_react(const EvRxOnCallSerial& e)

void goby::acomms::fsm::OnCall::in_state_react( const EvTxOnCallSerial& )
{
const static double target_byte_rate = (context<IridiumDriverFSM>().driver_cfg().GetExtension(IridiumDriverConfig::target_bit_rate) / static_cast<double>(goby::acomms::BITS_IN_BYTE));

const double send_wait = last_bytes_sent() / target_byte_rate;

double now = goby_time<double>();
boost::circular_buffer<protobuf::ModemTransmission>& data_out = context<IridiumDriverFSM>().data_out();
if(!data_out.empty())
if(!data_out.empty() && (now > last_tx_time() + send_wait))
{
// serialize the (protobuf) message
std::string bytes;
data_out.front().SerializeToString(&bytes);

serialize_iridium_modem_message(&bytes, data_out.front());
// frame message
std::string rudics_packet;
serialize_rudics_packet(bytes, &rudics_packet);

context<IridiumDriverFSM>().serial_tx_buffer().push_back(rudics_packet);
data_out.pop_front();

set_last_tx_time(goby_time<double>());
set_last_bytes_sent(rudics_packet.size());
set_last_tx_time(now);
}
}

Expand Down
32 changes: 5 additions & 27 deletions src/acomms/modemdriver/iridium_driver_fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ namespace goby
struct EvSendBye : boost::statechart::event< EvSendBye > {};


struct EvZMQConnect : boost::statechart::event< EvZMQConnect > {};
struct EvZMQDisconnect : boost::statechart::event< EvZMQDisconnect > {};

struct EvConfigured : boost::statechart::event< EvConfigured > {};
struct EvSBDBeginData : boost::statechart::event< EvSBDBeginData >
{
Expand Down Expand Up @@ -144,7 +141,6 @@ namespace goby

struct Online;
struct OnCall;
struct OnZMQCall;
struct NotOnCall;

struct SBD;
Expand Down Expand Up @@ -426,37 +422,19 @@ namespace goby
struct NotOnCall : boost::statechart::simple_state<NotOnCall, Active::orthogonal<1> >, StateNotify
{
typedef boost::mpl::list<
boost::statechart::transition< EvConnect, OnCall >,
boost::statechart::transition< EvZMQConnect, OnZMQCall >
boost::statechart::transition< EvConnect, OnCall >
> reactions;

NotOnCall() : StateNotify("NotOnCall") {}
~NotOnCall() {}
};

struct OnZMQCall : boost::statechart::simple_state<OnZMQCall, Active::orthogonal<1> >, StateNotify, OnCallBase
{

OnZMQCall() : StateNotify("OnZMQCall") { }
~OnZMQCall() {}

void in_state_react( const EvSendBye& )
{
set_bye_sent(true);
}

typedef boost::mpl::list<
boost::statechart::transition< EvZMQDisconnect, NotOnCall >,
boost::statechart::in_state_reaction< EvSendBye, OnZMQCall, &OnZMQCall::in_state_react >
> reactions;

};

struct OnCall : boost::statechart::state<OnCall, Active::orthogonal<1> >, StateNotify, OnCallBase
{
public:

OnCall(my_context ctx) : my_base(ctx), StateNotify("OnCall")
OnCall(my_context ctx) : my_base(ctx), StateNotify("OnCall")
{
// add a brief identifier that is *different* than the "~" which is what PPP uses
// add a carriage return to clear out any garbage
Expand All @@ -468,14 +446,14 @@ namespace goby
}
~OnCall() {
// signal the disconnect event for the command state to handle
glog.is(goby::common::logger::DEBUG1) && glog << group("iridiumdriver") << "Sent " << total_bytes_sent() << " bytes on this call." << std::endl;
post_event(EvDisconnect());
}

void in_state_react( const EvRxOnCallSerial& );
void in_state_react( const EvTxOnCallSerial& );
void in_state_react( const EvSendBye& );



typedef boost::mpl::list<
boost::statechart::transition< EvNoCarrier, NotOnCall >,
boost::statechart::in_state_reaction< EvRxOnCallSerial, OnCall, &OnCall::in_state_react >,
Expand All @@ -485,7 +463,7 @@ namespace goby
> reactions;

private:


};

Expand Down
Loading

0 comments on commit 594c527

Please sign in to comment.