diff --git a/lib/bladerf/bladerf_common.cc b/lib/bladerf/bladerf_common.cc
index 7fde952f8ab45eec32a5e22b9d52afaf070bb701..ed9a8f2136d9dca6aba3b9c5fa33ab3af4f73a3b 100644
--- a/lib/bladerf/bladerf_common.cc
+++ b/lib/bladerf/bladerf_common.cc
@@ -290,6 +290,8 @@ void bladerf_common::init(dict_t const &dict, bladerf_direction direction)
                   % get_clock_source()));
   }
 
+
+
   if (dict.count("smb")) {
     set_smb_frequency(boost::lexical_cast<double>(_get(dict, "smb")));
     BLADERF_INFO(boost::str(boost::format("SMB frequency set to %f Hz")
@@ -459,6 +461,35 @@ std::string bladerf_common::get_pmic_value(const std::string &reg_name)
 
 }
 
+void bladerf_common::setup_trigger(bladerf_channel ch, bladerf_trigger_signal signal, bool master)
+{
+    auto status = bladerf_trigger_init(_dev.get(), ch, signal, &_triggers[ch]);
+    if (status != 0) {
+      BLADERF_THROW_STATUS(status, "bladerf_trigger_init failed");
+    }
+    _triggers[ch].role  = master ? BLADERF_TRIGGER_ROLE_MASTER : BLADERF_TRIGGER_ROLE_SLAVE;
+    // Arm the triggering functionality
+    status = bladerf_trigger_arm(_dev.get(), &_triggers[ch], true, 0, 0);
+    if (status != 0) {
+      BLADERF_THROW_STATUS(status, "bladerf_trigger_arm failed");
+    }
+}
+
+void bladerf_common::fire_trigger()
+{
+    for(auto & trigger: _triggers)
+    {
+        if(trigger.second.role == BLADERF_TRIGGER_ROLE_MASTER)
+        {
+            auto status = bladerf_trigger_fire(_dev.get(), &trigger.second);
+            if (status != 0) {
+              BLADERF_THROW_STATUS(status, "bladerf_trigger_fire failed");
+            }
+            return;
+        }
+    }
+}
+
 void bladerf_common::set_verbosity(std::string const &verbosity)
 {
   bladerf_log_level l;
diff --git a/lib/bladerf/bladerf_common.h b/lib/bladerf/bladerf_common.h
index 54d1f88948a095327ee793d873731c7bf2ef22e3..4ed1c437eebdfbe77793cd3f99b768de12dba036 100644
--- a/lib/bladerf/bladerf_common.h
+++ b/lib/bladerf/bladerf_common.h
@@ -58,6 +58,10 @@ typedef std::map<bladerf_channel, bool> bladerf_channel_enable_map;
 /* Mapping of bladerf_channel to gnuradio port/chan */
 typedef std::map<bladerf_channel, int> bladerf_channel_map;
 
+/* Mapping of bladerf_trigger to gnuradio port/chan */
+typedef std::map<bladerf_channel, bladerf_trigger> bladerf_trigger_map;
+
+
 /* Convenience macros for throwing a runtime error */
 #define BLADERF_THROW(message)                                              \
   {                                                                         \
@@ -175,6 +179,10 @@ protected:
       return value;
   }
 
+  void setup_trigger(bladerf_channel ch, bladerf_trigger_signal, bool master);
+  void fire_trigger();
+
+
   /* Set libbladeRF verbosity */
   void set_verbosity(std::string const &verbosity);
 
@@ -269,6 +277,7 @@ protected:
 
   bladerf_channel_map _chanmap; /**< map of antennas to channels */
   bladerf_channel_enable_map _enables;  /**< enabled channels */
+  bladerf_trigger_map _triggers;     /**< trigger for */
 
   /*****************************************************************************
    * Protected constants
diff --git a/lib/bladerf/bladerf_sink_c.cc b/lib/bladerf/bladerf_sink_c.cc
index 928f8430c48836e34f9ef1cf6e25b062d7fddc1e..ca187460e20c8e07bd43d7f240b6d1f7eb91440c 100644
--- a/lib/bladerf/bladerf_sink_c.cc
+++ b/lib/bladerf/bladerf_sink_c.cc
@@ -65,7 +65,7 @@ bladerf_sink_c_sptr make_bladerf_sink_c(const std::string &args)
  * The private constructor
  */
 bladerf_sink_c::bladerf_sink_c(const std::string &args) :
-  gr::sync_block( "bladerf_sink_c",
+  common_sync_block( "bladerf_sink_c",
                   args_to_io_signature(args),
                   gr::io_signature::make(0, 0, 0)),
   _16icbuf(NULL),
@@ -73,18 +73,7 @@ bladerf_sink_c::bladerf_sink_c(const std::string &args) :
   _in_burst(false),
   _running(false)
 {
-    message_port_register_in(pmt::mp("pmic_in"));
-    message_port_register_out(pmt::mp("pmic_out"));
-
-    set_msg_handler(pmt::mp("pmic_in"),[=](const pmt::pmt_t & msg)
-    {
-        auto type = pmt::symbol_to_string(msg);
-        auto value = get_pmic_value(type);
-        auto pair = pmt::cons(msg,pmt::string_to_symbol(value));
-        message_port_pub(pmt::mp("pmic_out"), pair);
-
-    });
-
+  setup_blade_messaging();
   dict_t dict = params_to_dict(args);
 
   /* Perform src/sink agnostic initializations */
diff --git a/lib/bladerf/bladerf_sink_c.h b/lib/bladerf/bladerf_sink_c.h
index 599a3ea5ba0974bc68ad632a164577c1d7c46ba9..ad0765ca71152afb051d948dc4970c3d13a8de22 100644
--- a/lib/bladerf/bladerf_sink_c.h
+++ b/lib/bladerf/bladerf_sink_c.h
@@ -21,7 +21,7 @@
 #ifndef INCLUDED_BLADERF_SINK_C_H
 #define INCLUDED_BLADERF_SINK_C_H
 
-#include <gnuradio/sync_block.h>
+#include "common_sync_block.h"
 #include "bladerf_common.h"
 
 #include "osmosdr/ranges.h"
@@ -51,8 +51,7 @@ typedef std::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
 bladerf_sink_c_sptr make_bladerf_sink_c(const std::string &args = "");
 
 class bladerf_sink_c :
-  public gr::sync_block,
-  protected bladerf_common
+  public common_sync_block
 {
 private:
   // The friend declaration allows bladerf_make_sink_c to
diff --git a/lib/bladerf/bladerf_source_c.cc b/lib/bladerf/bladerf_source_c.cc
index 535dd03470d3fd02f78d9fa4be65881be3591d09..0fc570f15f003503958733c281db926b84f0320a 100644
--- a/lib/bladerf/bladerf_source_c.cc
+++ b/lib/bladerf/bladerf_source_c.cc
@@ -65,7 +65,7 @@ bladerf_source_c_sptr make_bladerf_source_c(const std::string &args)
  * The private constructor
  */
 bladerf_source_c::bladerf_source_c(const std::string &args) :
-  gr::sync_block( "bladerf_source_c",
+  common_sync_block( "bladerf_source_c",
                   gr::io_signature::make(0, 0, 0),
                   args_to_io_signature(args)),
   _16icbuf(NULL),
@@ -79,17 +79,7 @@ bladerf_source_c::bladerf_source_c(const std::string &args) :
   /* Perform src/sink agnostic initializations */
   init(dict, BLADERF_RX);
 
-  message_port_register_in(pmt::mp("pmic_in"));
-  message_port_register_out(pmt::mp("pmic_out"));
-
-  set_msg_handler(pmt::mp("pmic_in"),[=](const pmt::pmt_t & msg)
-  {
-      auto type = pmt::symbol_to_string(msg);
-      auto value = get_pmic_value(type);
-      auto pair = pmt::cons(msg,pmt::string_to_symbol(value));
-      message_port_pub(pmt::mp("pmic_out"), pair);
-
-  });
+  setup_blade_messaging();
 
   /* Handle setting of sampling mode */
   if (dict.count("sampling")) {
diff --git a/lib/bladerf/bladerf_source_c.h b/lib/bladerf/bladerf_source_c.h
index b0b9b3d6304697cbe3bd7eb33fccd9d0f57b2be4..ae4bf6230d5577c87731d32d6286010f9508f04c 100644
--- a/lib/bladerf/bladerf_source_c.h
+++ b/lib/bladerf/bladerf_source_c.h
@@ -21,7 +21,7 @@
 #ifndef INCLUDED_BLADERF_SOURCE_C_H
 #define INCLUDED_BLADERF_SOURCE_C_H
 
-#include <gnuradio/sync_block.h>
+#include "common_sync_block.h"
 #include "bladerf_common.h"
 #include "osmosdr/ranges.h"
 
@@ -50,8 +50,7 @@ typedef std::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
 bladerf_source_c_sptr make_bladerf_source_c(const std::string &args = "");
 
 class bladerf_source_c :
-  public gr::sync_block,
-  protected bladerf_common
+  public common_sync_block
 {
 private:
   // The friend declaration allows bladerf_make_source_c to
diff --git a/lib/bladerf/common_sync_block.h b/lib/bladerf/common_sync_block.h
new file mode 100644
index 0000000000000000000000000000000000000000..780393a8022ae61b9bd87b9c8da4305185e8646a
--- /dev/null
+++ b/lib/bladerf/common_sync_block.h
@@ -0,0 +1,35 @@
+#pragma once
+#include <gnuradio/sync_block.h>
+#include "bladerf_common.h"
+
+class common_sync_block: public gr::sync_block, public bladerf_common
+{
+public:
+   common_sync_block(const std::string& name,
+               gr::io_signature::sptr input_signature,
+               gr::io_signature::sptr output_signature)
+               : gr::sync_block(name, input_signature, output_signature)
+   {
+   }
+   void setup_blade_messaging()
+   {
+        message_port_register_in(pmt::mp("pmic_in"));
+        message_port_register_in(pmt::mp("fire"));
+        message_port_register_out(pmt::mp("pmic_out"));
+
+        set_msg_handler(pmt::mp("pmic_in"),[=](const pmt::pmt_t & msg)
+        {
+            auto type = pmt::symbol_to_string(msg);
+            auto value = get_pmic_value(type);
+            auto pair = pmt::cons(msg,pmt::string_to_symbol(value));
+            message_port_pub(pmt::mp("pmic_out"), pair);
+
+        });
+        set_msg_handler(pmt::mp("fire"),[=](const pmt::pmt_t & msg)
+        {
+            fire_trigger();
+        });
+   }
+};
+
+
diff --git a/lib/common_hier_block.h b/lib/common_hier_block.h
new file mode 100644
index 0000000000000000000000000000000000000000..fdf0d5ef410465429cce86ab718e425c0c04ba8d
--- /dev/null
+++ b/lib/common_hier_block.h
@@ -0,0 +1,29 @@
+#pragma once
+#include <gnuradio/hier_block2.h>
+
+class common_hier_block: public gr::hier_block2
+{
+public:
+   common_hier_block(const std::string& name,
+               gr::io_signature::sptr input_signature,
+               gr::io_signature::sptr output_signature)
+               : gr::hier_block2(name, input_signature, output_signature)
+   {
+   }
+   void setup_message_ports()
+   {
+        message_port_register_hier_in(pmt::mp("fire"));
+        message_port_register_hier_in(pmt::mp("pmic_in"));
+        message_port_register_hier_out(pmt::mp("pmic_out"));
+
+   }
+   template<typename T>
+   void setup_device_connects(T device)
+   {
+   	msg_connect(self(), pmt::mp("fire"), device, pmt::mp("fire"));
+        msg_connect(self(), pmt::mp("pmic_in"), device, pmt::mp("pmic_in"));
+        msg_connect(device,pmt::mp("pmic_out"), self(), pmt::mp("pmic_out"));
+   }
+   
+   
+};
diff --git a/lib/sink_impl.cc b/lib/sink_impl.cc
index 126e3d7aaf14c33abdc14f27e7bad4d3f07c15bf..553d85737c7dc5e53da8e8f897ce967c005da948 100644
--- a/lib/sink_impl.cc
+++ b/lib/sink_impl.cc
@@ -5,7 +5,7 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#include <gnuradio/io_signature.h>
+#include "common_hier_block.h"
 #include "sink_impl.h"
 #include "arg_helpers.h"
 
@@ -22,13 +22,12 @@ namespace gr {
      * The private constructor
      */
     sink_impl::sink_impl(const std::string & args)
-      : gr::hier_block2("sink_impl",
+      : common_hier_block("sink_impl",
                         args_to_io_signature(args),
                         gr::io_signature::make(0, 0, 0))
       , sample_rate_(0)
     {
-        message_port_register_hier_in(pmt::mp("pmic_in"));
-        message_port_register_hier_out(pmt::mp("pmic_out"));
+        setup_message_ports();
 
         auto dev_list = bladerf_sink_c::get_devices();
         if(dev_list.size() == 0)
@@ -36,8 +35,7 @@ namespace gr {
                                      "(check the connection and/or udev rules).");
 
         device_ = make_bladerf_sink_c( args ); //todo: get by id from block args
-        msg_connect(self(), pmt::mp("pmic_in"), device_, pmt::mp("pmic_in"));
-        msg_connect(device_,pmt::mp("pmic_out"), self(), pmt::mp("pmic_out"));
+        setup_device_connects(device_);
     }
 
     /*
diff --git a/lib/source_impl.cc b/lib/source_impl.cc
index 8fdc13a3f64b6dfc8b64728ba39f8a75c3b84b93..fc53c8ea861005282f21e39bd54de935c39f4a68 100644
--- a/lib/source_impl.cc
+++ b/lib/source_impl.cc
@@ -5,7 +5,7 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
-#include <gnuradio/io_signature.h>
+#include "common_hier_block.h"
 #include "source_impl.h"
 #include "arg_helpers.h"
 
@@ -21,12 +21,11 @@ namespace gr {
      * The private constructor
      */
     source_impl::source_impl(const std::string & args)
-      : gr::hier_block2("source",
+      : common_hier_block("source",
               gr::io_signature::make(0,0,0),
               args_to_io_signature(args))
     {
-        message_port_register_hier_in(pmt::mp("pmic_in"));
-        message_port_register_hier_out(pmt::mp("pmic_out"));
+        setup_message_ports();
 
         auto dev_list = bladerf_source_c::get_devices();
         if(dev_list.size() == 0)
@@ -50,12 +49,9 @@ namespace gr {
   #else
           connect(device_, i, self(), i);          
   #endif
-          msg_connect(self(), pmt::mp("pmic_in"), device_, pmt::mp("pmic_in"));
-          msg_connect(device_,pmt::mp("pmic_out"), self(), pmt::mp("pmic_out"));
-        }
-
-
 
+        }
+        setup_device_connects(device_);
      }
 
     source_impl::~source_impl()