diff --git a/flight/pios/stm32f30x/pios_usb.c b/flight/pios/stm32f30x/pios_usb.c
index 63b5c5db2..f7a36e825 100644
--- a/flight/pios/stm32f30x/pios_usb.c
+++ b/flight/pios/stm32f30x/pios_usb.c
@@ -7,8 +7,9 @@
  * @{
  *
  * @file       pios_usb.c
- * @author     The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
- * @author     Tau Labs, http://taulabs.org, Copyright (C) 2012-2013
+ * @author     The LibrePilot Project, http://www.librepilot.org (C) 2017.
+ *             Tau Labs, http://taulabs.org, Copyright (C) 2012-2013
+ *             The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
  * @brief      USB device functions (STM32 dependent code)
  * @see        The GNU Public License (GPL) Version 3
  *
@@ -44,6 +45,13 @@
 /* Rx/Tx status */
 static bool transfer_possible = false;
 
+#ifdef PIOS_INCLUDE_FREERTOS
+struct {
+    void     (*callback)(bool connected, uint32_t context);
+    uint32_t context;
+} connectionState_cb_list[3];
+#endif
+
 /* USB activity detection */
 static volatile bool sof_seen_since_reset = false;
 
@@ -55,6 +63,9 @@ struct pios_usb_dev {
     enum pios_usb_dev_magic   magic;
     const struct pios_usb_cfg *cfg;
 };
+#ifdef PIOS_INCLUDE_FREERTOS
+static void raiseConnectionStateCallback(bool connected);
+#endif
 
 /**
  * @brief Validate the usb device structure
@@ -195,6 +206,10 @@ int32_t PIOS_USB_ChangeConnectionState(bool Connected)
 #endif
     }
 
+#ifdef PIOS_INCLUDE_FREERTOS
+    raiseConnectionStateCallback(Connected);
+#endif
+
     return 0;
 }
 
@@ -282,6 +297,36 @@ void SUSP_Callback(void)
     sof_seen_since_reset = false;
 }
 
+#ifdef PIOS_INCLUDE_FREERTOS
+void PIOS_USB_RegisterConnectionStateCallback(void (*connectionStateCallback)(bool connected, uint32_t context), uint32_t context)
+{
+    PIOS_Assert(connectionStateCallback);
+
+    for (uint32_t i = 0; i < NELEMENTS(connectionState_cb_list); i++) {
+        if (connectionState_cb_list[i].callback == NULL) {
+            connectionState_cb_list[i].callback = connectionStateCallback;
+            connectionState_cb_list[i].context  = context;
+            return;
+        }
+    }
+
+    PIOS_Assert(0);
+}
+
+static void raiseConnectionStateCallback(bool connected)
+{
+    uint32_t i = 0;
+
+    while (i < NELEMENTS(connectionState_cb_list) && connectionState_cb_list[i].callback != NULL) {
+        connectionState_cb_list[i].callback(connected, connectionState_cb_list[i].context);
+        i++;
+    }
+}
+#else /* PIOS_INCLUDE_FREERTOS */
+void PIOS_USB_RegisterConnectionStateCallback(__attribute__((unused)) void (*connectionStateCallback)(bool connected, uint32_t context), __attribute__((unused)) uint32_t context)
+{}
+#endif /* PIOS_INCLUDE_FREERTOS */
+
 #endif /* if defined(PIOS_INCLUDE_USB) */
 
 /**
diff --git a/flight/pios/stm32f30x/pios_usb_cdc.c b/flight/pios/stm32f30x/pios_usb_cdc.c
index d96a67dc6..186fb95b4 100644
--- a/flight/pios/stm32f30x/pios_usb_cdc.c
+++ b/flight/pios/stm32f30x/pios_usb_cdc.c
@@ -43,6 +43,8 @@
 static void PIOS_USB_CDC_RegisterTxCallback(uint32_t usbcdc_id, pios_com_callback tx_out_cb, uint32_t context);
 static void PIOS_USB_CDC_RegisterRxCallback(uint32_t usbcdc_id, pios_com_callback rx_in_cb, uint32_t context);
 static void PIOS_USB_CDC_RegisterBaudRateCallback(uint32_t usbcdc_id, pios_com_callback_baud_rate baud_rate_cb, uint32_t context);
+static void PIOS_USB_CDC_RegisterAvailableCallback(uint32_t usbcdc_id, pios_com_callback_available baud_rate_cb, uint32_t context);
+static void PIOS_USB_CDC_ChangeConnectionState(bool connected, uint32_t usbcdc_id);
 static void PIOS_USB_CDC_TxStart(uint32_t usbcdc_id, uint16_t tx_bytes_avail);
 static void PIOS_USB_CDC_RxStart(uint32_t usbcdc_id, uint16_t rx_bytes_avail);
 static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id);
@@ -54,6 +56,7 @@ const struct pios_com_driver pios_usb_cdc_com_driver = {
     .bind_rx_cb = PIOS_USB_CDC_RegisterRxCallback,
     .bind_baud_rate_cb = PIOS_USB_CDC_RegisterBaudRateCallback,
     .available  = PIOS_USB_CDC_Available,
+    .bind_available_cb = PIOS_USB_CDC_RegisterAvailableCallback,
 };
 
 enum pios_usb_cdc_dev_magic {
@@ -73,6 +76,8 @@ struct pios_usb_cdc_dev {
 
     pios_com_callback_baud_rate baud_rate_cb;
     uint32_t baud_rate_context;
+    pios_com_callback_available available_cb;
+    uint32_t available_context;
 
     uint8_t  rx_packet_buffer[PIOS_USB_BOARD_CDC_DATA_LENGTH];
     /*
@@ -158,6 +163,8 @@ int32_t PIOS_USB_CDC_Init(uint32_t *usbcdc_id, const struct pios_usb_cdc_cfg *cf
     pEpInt_IN[cfg->data_tx_ep - 1]  = PIOS_USB_CDC_DATA_EP_IN_Callback;
     pEpInt_OUT[cfg->data_rx_ep - 1] = PIOS_USB_CDC_DATA_EP_OUT_Callback;
 
+    PIOS_USB_RegisterConnectionStateCallback(PIOS_USB_CDC_ChangeConnectionState, (uint32_t)usb_cdc_dev);
+
     *usbcdc_id = (uint32_t)usb_cdc_dev;
 
     return 0;
@@ -367,8 +374,7 @@ static uint32_t PIOS_USB_CDC_Available(uint32_t usbcdc_id)
 
     PIOS_Assert(valid);
 
-    return (PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) &&
-            (control_line_state & USB_CDC_CONTROL_LINE_STATE_DTE_PRESENT)) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE;
+    return PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id) ? COM_AVAILABLE_RXTX : COM_AVAILABLE_NONE;
 }
 
 static struct usb_cdc_line_coding line_coding = {
@@ -488,5 +494,33 @@ void PIOS_USB_CDC_SetLineCoding_Completed()
     }
 }
 
+static void PIOS_USB_CDC_ChangeConnectionState(__attribute__((unused)) bool connected, uint32_t usbcdc_id)
+{
+    struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
+
+    bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
+
+    PIOS_Assert(valid);
+
+    if (usb_cdc_dev->available_cb) {
+        (usb_cdc_dev->available_cb)(usb_cdc_dev->available_context, PIOS_USB_CDC_Available(usbcdc_id));
+    }
+}
+
+static void PIOS_USB_CDC_RegisterAvailableCallback(uint32_t usbcdc_id, pios_com_callback_available available_cb, uint32_t context)
+{
+    struct pios_usb_cdc_dev *usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id;
+
+    bool valid = PIOS_USB_CDC_validate(usb_cdc_dev);
+
+    PIOS_Assert(valid);
+
+    /*
+     * Order is important in these assignments since ISR uses _cb
+     * field to determine if it's ok to dereference _cb and _context
+     */
+    usb_cdc_dev->available_context = context;
+    usb_cdc_dev->available_cb = available_cb;
+}
 
 #endif /* PIOS_INCLUDE_USB_CDC */