diff --git a/epicardium/ble/ble.c b/epicardium/ble/ble.c
index a667f9d1f739d8f7b15210971adb0caec78e1bd6..db80c577024492f8015b4c25d96c8d6478eca9a1 100644
--- a/epicardium/ble/ble.c
+++ b/epicardium/ble/ble.c
@@ -44,7 +44,7 @@ static TimerHandle_t timerWakeup = NULL;
 static int lasttick              = 0;
 
 /*! \brief  Stack initialization for app. */
-extern void StackInit(void);
+extern void StackInitScanner(void);
 extern void AppInit(void);
 extern void bleuart_init(void);
 extern void bleFileTransfer_init(void);
@@ -246,7 +246,7 @@ void vBleTask(void *pvParameters)
 	vTaskDelay(pdMS_TO_TICKS(500));
 
 	WsfInit();
-	StackInit();
+	StackInitScanner();
 	BbBleDrvSetTxPower(0);
 	setAddress();
 
diff --git a/epicardium/ble/ble_main.c b/epicardium/ble/ble_main.c
index a20b197d92c0224ccdad664dccba7d6be717b22d..6ac4be7c8e63941689efff8d81c50411e5ec2ad0 100644
--- a/epicardium/ble/ble_main.c
+++ b/epicardium/ble/ble_main.c
@@ -35,163 +35,102 @@
 #include "bas/bas_api.h"
 #include "hrps/hrps_api.h"
 #include "rscp/rscp_api.h"
+#include "scanner_api.h"
+
 
 /**************************************************************************************************
   Macros
 **************************************************************************************************/
 
-/*! WSF message event starting value */
-#define BLE_MSG_START               0xA0
 
-/*! WSF message event enumeration */
-enum
-{
-  BLE_BATT_TIMER_IND = BLE_MSG_START,                     /*! Battery measurement timer expired */
-};
+#define TEST_TIMER_IND   0x99
 
 /**************************************************************************************************
-  Data Types
-**************************************************************************************************/
+ Local Variables
+ **************************************************************************************************/
 
-/*! Application message type */
-typedef union
+/*! application control block */
+struct
 {
-  wsfMsgHdr_t     hdr;
-  dmEvt_t         dm;
-  attsCccEvt_t    ccc;
-  attEvt_t        att;
-} bleMsg_t;
-
-/**************************************************************************************************
-  Configurable Parameters
-**************************************************************************************************/
+    wsfHandlerId_t    handlerId;                      /*! WSF hander ID */
+    bool_t            scanning;                       /*! TRUE if scanning */
+} scannerCb;
 
-/*! configurable parameters for advertising */
-static const appAdvCfg_t bleAdvCfg =
+/*! test control block */
+struct
 {
-  {0,             0,              0},                  /*! Advertising durations in ms */
-  {500/0.625,     4000/0.625,     0}                   /*! Advertising intervals in 0.625 ms units */
-};
-
-/*! configurable parameters for slave */
-static const appSlaveCfg_t bleSlaveCfg =
-{
-  1,                                      /*! Maximum connections */
-};
-
-/*! configurable parameters for security */
-static const appSecCfg_t bleSecCfg =
-{
-  DM_AUTH_BOND_FLAG | DM_AUTH_SC_FLAG,    /*! Authentication and bonding flags */
-  0,                                      /*! Initiator key distribution flags */
-  DM_KEY_DIST_LTK,                        /*! Responder key distribution flags */
-  FALSE,                                  /*! TRUE if Out-of-band pairing data is present */
-  TRUE                                    /*! TRUE to initiate security upon connection */
-};
-
-/*! configurable parameters for connection parameter update */
-static const appUpdateCfg_t bleUpdateCfg =
-{
-  6000,                                   /*! Connection idle period in ms before attempting
-                                              connection parameter update; set to zero to disable */
-  800/1.25,                               /*! Minimum connection interval in 1.25ms units */
-  1000/1.25,                              /*! Maximum connection interval in 1.25ms units */
-  0,                                      /*! Connection latency */
-  9000/10,                                /*! Supervision timeout in 10ms units */
-  5                                       /*! Number of update attempts before giving up */
-};
-
-/*! battery measurement configuration */
-static const basCfg_t bleBasCfg =
-{
-  30,       /*! Battery measurement timer expiration period in seconds */
-  1,        /*! Perform battery measurement after this many timer periods */
-  100       /*! Send battery level notification to peer when below this level. */
-};
-
-/*! SMP security parameter configuration */
-static const smpCfg_t bleSmpCfg =
-{
-  3000,                                   /*! 'Repeated attempts' timeout in msec */
-  SMP_IO_DISP_YES_NO,                     /*! I/O Capability */
-  7,                                      /*! Minimum encryption key length */
-  16,                                     /*! Maximum encryption key length */
-  3,                                      /*! Attempts to trigger 'repeated attempts' timeout */
-  DM_AUTH_MITM_FLAG,                      /*! Device authentication requirements */
-};
-
-/* Configuration structure */
-static const attCfg_t bleAttCfg =
-{
-  15,                                  /* ATT server service discovery connection idle timeout in seconds */
-  241,                                 /* desired ATT MTU */
-  ATT_MAX_TRANS_TIMEOUT,               /* transaction timeout in seconds */
-  1                                    /* number of queued prepare writes supported by server */
-};
+    unsigned int counter;
+    wsfTimer_t timer;
+} testCb;
 
 /**************************************************************************************************
-  Advertising Data
-**************************************************************************************************/
+ Configurable Parameters
+ **************************************************************************************************/
 
-/*! advertising data, discoverable mode */
-static const uint8_t bleAdvDataDisc[] =
+#ifdef BTLE_APP_USE_LEGACY_API
+/*! configurable parameters for master */
+static const appMasterCfg_t scannerMasterCfg =
 {
-  /*! flags */
-  2,                                      /*! length */
-  DM_ADV_TYPE_FLAGS,                      /*! AD type */
-  DM_FLAG_LE_GENERAL_DISC |               /*! flags */
-  DM_FLAG_LE_BREDR_NOT_SUP,
-
-  /*! tx power */
-  2,                                      /*! length */
-  DM_ADV_TYPE_TX_POWER,                   /*! AD type */
-  0,                                      /*! tx power */
-
-  /*! service UUID list */
-  5,                                      /*! length */
-  DM_ADV_TYPE_16_UUID,                    /*! AD type */
-  UINT16_TO_BYTES(ATT_UUID_DEVICE_INFO_SERVICE),
-  UINT16_TO_BYTES(ATT_UUID_BATTERY_SERVICE)
+    420,                                     /*! The scan interval, in 0.625 ms units */
+    420,                                     /*! The scan window, in 0.625 ms units  */
+    0,                                       /*! The scan duration in ms */
+    DM_DISC_MODE_NONE,                       /*! The GAP discovery mode */
+#ifdef BTLE_APP_USE_ACTIVE_SCANNING
+    DM_SCAN_TYPE_ACTIVE
+#else /* BTLE_APP_USE_ACTIVE_SCANNING */
+    DM_SCAN_TYPE_PASSIVE
+#endif /* BTLE_APP_USE_ACTIVE_SCANNING */
+    /*!< The scan type (active or passive) */
 };
 
-/*! scan data, discoverable mode */
-static const uint8_t bleScanDataDisc[] =
+#else /* BTLE_APP_USE_LEGACY_API */
+/*! configurable parameters for extended master */
+static const uint8_t scannerExtMasterScanPhysCfg =
+HCI_SCAN_PHY_LE_1M_BIT |
+//HCI_SCAN_PHY_LE_2M_BIT |
+//HCI_SCAN_PHY_LE_CODED_BIT |
+0;
+static const appExtMasterCfg_t scannerExtMasterCfg =
 {
-  /*! device name */
-  7,                                      /*! length */
-  DM_ADV_TYPE_LOCAL_NAME,                 /*! AD type */
-  'c','a','r','d','1','0'
+    { 420, 420, 420 },                       /*! \brief The scan interval, in 0.625 ms units */
+    { 420, 420, 420 },                       /*! \brief The scan window, in 0.625 ms units.   Must be less than or equal to scan interval. */
+    0,                                       /*! \brief The scan duration in ms.  Set to zero or both duration and period to non-zero to scan until stopped. */
+    0,                                       /*! \brief The scan period, in 1.28 sec units.  Set to zero to disable periodic scanning. */
+    DM_DISC_MODE_NONE,                       /*! \brief The GAP discovery mode (general, limited, or none) */
+#ifdef BTLE_APP_USE_ACTIVE_SCANNING
+    {
+        DM_SCAN_TYPE_ACTIVE,
+        DM_SCAN_TYPE_ACTIVE,
+        DM_SCAN_TYPE_ACTIVE
+    }
+#else /* BTLE_APP_USE_ACTIVE_SCANNING */
+    {
+        DM_SCAN_TYPE_PASSIVE,
+        DM_SCAN_TYPE_PASSIVE,
+        DM_SCAN_TYPE_PASSIVE
+    }
+#endif /* BTLE_APP_USE_ACTIVE_SCANNING */
+    /*!< \brief The scan type (active or passive) */
 };
 
+#endif /* BTLE_APP_USE_LEGACY_API */
+
 /**************************************************************************************************
-  Client Characteristic Configuration Descriptors
-**************************************************************************************************/
+ ATT Client Discovery Data
+ **************************************************************************************************/
 
-/*! enumeration of client characteristic configuration descriptors */
+/*! Discovery states:  enumeration of services to be discovered */
 enum
 {
-  BLE_GATT_SC_CCC_IDX,                    /*! GATT service, service changed characteristic */
-  BLE_BATT_LVL_CCC_IDX,                   /*! Battery service, battery level characteristic */
-  BLE_NUM_CCC_IDX
-};
-
-/*! client characteristic configuration descriptors settings, indexed by above enumeration */
-static const attsCccSet_t bleCccSet[BLE_NUM_CCC_IDX] =
-{
-  /* cccd handle          value range               security level */
-  {GATT_SC_CH_CCC_HDL,    ATT_CLIENT_CFG_INDICATE,  DM_SEC_LEVEL_NONE},   /* BLE_GATT_SC_CCC_IDX */
-  {BATT_LVL_CH_CCC_HDL,   ATT_CLIENT_CFG_NOTIFY,    DM_SEC_LEVEL_NONE},   /* BLE_BATT_LVL_CCC_IDX */
+    SCANNER_DISC_GATT_SVC,      /*! GATT service */
+    SCANNER_DISC_GAP_SVC,       /*! GAP service */
+    SCANNER_DISC_WP_SVC,        /*! ARM Ltd. proprietary service */
+    SCANNER_DISC_SVC_MAX        /*! Discovery complete */
 };
 
 /**************************************************************************************************
-  Global Variables
-**************************************************************************************************/
-
-/*! WSF handler ID */
-wsfHandlerId_t bleHandlerId;
-
-
-static void BleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
+ ATT Client Configuration Data
+ **************************************************************************************************/
 /*************************************************************************************************/
 /*!
  *  \brief  Application DM callback.
@@ -201,148 +140,176 @@ static void BleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
  *  \return None.
  */
 /*************************************************************************************************/
-static void bleDmCback(dmEvt_t *pDmEvt)
+static void scannerDmCback(dmEvt_t *pDmEvt)
 {
-  dmEvt_t *pMsg;
-  uint16_t len;
-
-  len = DmSizeOfEvt(pDmEvt);
-
-  if ((pMsg = WsfMsgAlloc(len)) != NULL)
-  {
-    memcpy(pMsg, pDmEvt, len);
-    WsfMsgSend(bleHandlerId, pMsg);
-  }
+    dmEvt_t   *pMsg;
+    uint16_t  len;
+    uint16_t  reportLen;
+    
+    len = DmSizeOfEvt(pDmEvt);
+    
+    if (pDmEvt->hdr.event == DM_SCAN_REPORT_IND)
+    {
+        reportLen = pDmEvt->scanReport.len;
+    }
+    else
+    {
+        reportLen = 0;
+    }
+    
+    if ((pMsg = WsfMsgAlloc(len + reportLen)) != NULL)
+    {
+        memcpy(pMsg, pDmEvt, len);
+        if (pDmEvt->hdr.event == DM_SCAN_REPORT_IND)
+        {
+            pMsg->scanReport.pData = (uint8_t *) ((uint8_t *) pMsg + len);
+            memcpy(pMsg->scanReport.pData, pDmEvt->scanReport.pData, reportLen);
+        }
+        WsfMsgSend(scannerCb.handlerId, pMsg);
+    }
 }
 
 /*************************************************************************************************/
 /*!
- *  \brief  Application ATT callback.
+ *  \brief  Perform actions on scan start.
  *
- *  \param  pEvt    ATT callback event
+ *  \param  pMsg    Pointer to DM callback event message.
  *
  *  \return None.
  */
 /*************************************************************************************************/
-static void bleAttCback(attEvt_t *pEvt)
+static void scannerScanStart(dmEvt_t *pMsg)
 {
-  attEvt_t *pMsg;
-
-  if ((pMsg = WsfMsgAlloc(sizeof(attEvt_t) + pEvt->valueLen)) != NULL)
-  {
-    memcpy(pMsg, pEvt, sizeof(attEvt_t));
-    pMsg->pValue = (uint8_t *) (pMsg + 1);
-    memcpy(pMsg->pValue, pEvt->pValue, pEvt->valueLen);
-    WsfMsgSend(bleHandlerId, pMsg);
-  }
+    if (pMsg->hdr.status == HCI_SUCCESS)
+    {
+        scannerCb.scanning = TRUE;
+    }
 }
 
 /*************************************************************************************************/
 /*!
- *  \brief  Application ATTS client characteristic configuration callback.
+ *  \brief  Perform actions on scan stop.
  *
- *  \param  pDmEvt  DM callback event
+ *  \param  pMsg    Pointer to DM callback event message.
  *
  *  \return None.
  */
 /*************************************************************************************************/
-static void bleCccCback(attsCccEvt_t *pEvt)
+static void scannerScanStop(dmEvt_t *pMsg)
 {
-  attsCccEvt_t  *pMsg;
-  appDbHdl_t    dbHdl;
-
-  /* if CCC not set from initialization and there's a device record */
-  if ((pEvt->handle != ATT_HANDLE_NONE) &&
-      ((dbHdl = AppDbGetHdl((dmConnId_t) pEvt->hdr.param)) != APP_DB_HDL_NONE))
-  {
-    /* store value in device database */
-    AppDbSetCccTblValue(dbHdl, pEvt->idx, pEvt->value);
-  }
-
-  if ((pMsg = WsfMsgAlloc(sizeof(attsCccEvt_t))) != NULL)
-  {
-    memcpy(pMsg, pEvt, sizeof(attsCccEvt_t));
-    WsfMsgSend(bleHandlerId, pMsg);
-  }
+    if (pMsg->hdr.status == HCI_SUCCESS)
+    {
+        scannerCb.scanning = FALSE;
+    }
 }
 
-
-
 /*************************************************************************************************/
 /*!
- *  \brief  Process CCC state change.
+ *  \brief  Handle a scan report.
  *
- *  \param  pMsg    Pointer to message.
+ *  \param  pMsg    Pointer to DM callback event message.
  *
  *  \return None.
  */
 /*************************************************************************************************/
-static void bleProcCccState(bleMsg_t *pMsg)
+static void scannerScanReport(dmEvt_t *pMsg)
 {
-  APP_TRACE_INFO3("ccc state ind value:%d handle:%d idx:%d", pMsg->ccc.value, pMsg->ccc.handle, pMsg->ccc.idx);
-
-  /* handle battery level CCC */
-  if (pMsg->ccc.idx == BLE_BATT_LVL_CCC_IDX)
-  {
-    if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY)
+    /* disregard if not scanning */
+    if (!scannerCb.scanning)
     {
-      BasMeasBattStart((dmConnId_t) pMsg->ccc.hdr.param, BLE_BATT_TIMER_IND, BLE_BATT_LVL_CCC_IDX);
+        return;
     }
-    else
-    {
-      BasMeasBattStop((dmConnId_t) pMsg->ccc.hdr.param);
-    }
-    return;
-  }
+    
+    printf("scannerScanReport() %x : %02x:%02x:%02x:%02x:%02x:%02x",pMsg->scanReport.addrType,
+           pMsg->scanReport.addr[5],
+           pMsg->scanReport.addr[4],
+           pMsg->scanReport.addr[3],
+           pMsg->scanReport.addr[2],
+           pMsg->scanReport.addr[1],
+           pMsg->scanReport.addr[0]);
+    
+    printf("  len %u, rssi %d, evtType %x, addrType %x\n", pMsg->scanReport.len, pMsg->scanReport.rssi, pMsg->scanReport.eventType, pMsg->scanReport.addrType);
 }
 
+#ifndef BTLE_APP_IGNORE_EXT_EVENTS
 /*************************************************************************************************/
 /*!
- *  \brief  Perform UI actions on connection close.
+ *  \brief  Handle a scan report.
  *
- *  \param  pMsg    Pointer to message.
+ *  \param  pMsg    Pointer to DM callback event message.
  *
  *  \return None.
  */
 /*************************************************************************************************/
-static void bleClose(bleMsg_t *pMsg)
+static void scannerExtScanReport(dmEvt_t *pMsg)
 {
-  /* stop battery measurement */
-  BasMeasBattStop((dmConnId_t) pMsg->hdr.param);
+    /* disregard if not scanning */
+    if (!scannerCb.scanning)
+    {
+        return;
+    }
+    
+    printf("scannerExtScanReport() %x : %02x:%02x:%02x:%02x:%02x:%02x", pMsg->extScanReport.addrType,
+           pMsg->extScanReport.addr[5],
+           pMsg->extScanReport.addr[4],
+           pMsg->extScanReport.addr[3],
+           pMsg->extScanReport.addr[2],
+           pMsg->extScanReport.addr[1],
+           pMsg->extScanReport.addr[0]);
+    
+    printf("  len %u, rssi %d, evtType %x, addrType %x\n", pMsg->extScanReport.len, pMsg->extScanReport.rssi, pMsg->extScanReport.eventType, pMsg->extScanReport.addrType);
 }
+#endif /* BTLE_APP_IGNORE_EXT_EVENTS */
 
 /*************************************************************************************************/
 /*!
- *  \brief  Set up advertising and other procedures that need to be performed after
- *          device reset.
+ *  \brief  Set up procedures that need to be performed after device reset.
  *
- *  \param  pMsg    Pointer to message.
+ *  \param  pMsg    Pointer to DM callback event message.
  *
  *  \return None.
  */
 /*************************************************************************************************/
-static void bleSetup(bleMsg_t *pMsg)
+static void scannerSetup(dmEvt_t *pMsg)
 {
-  /* set advertising and scan response data for discoverable mode */
-  AppAdvSetData(APP_ADV_DATA_DISCOVERABLE, sizeof(bleAdvDataDisc), (uint8_t *) bleAdvDataDisc);
-  AppAdvSetData(APP_SCAN_DATA_DISCOVERABLE, sizeof(bleScanDataDisc), (uint8_t *) bleScanDataDisc);
-
-  /* set advertising and scan response data for connectable mode */
-  AppAdvSetData(APP_ADV_DATA_CONNECTABLE, 0, NULL);
-  AppAdvSetData(APP_SCAN_DATA_CONNECTABLE, 0, NULL);
-
+    scannerCb.scanning = FALSE;
+    
+    testCb.timer.handlerId = scannerCb.handlerId;
+    testCb.timer.msg.event = TEST_TIMER_IND;
+    WsfTimerStartMs(&testCb.timer, 1000);
+    
+    /* If this is defined to one, scanning will be limited to the peer */
 #if 0
-  /* TODO: card10: until we have an BLE dialog, be discoverable and bondable always */
-  /* start advertising; automatically set connectable/discoverable mode and bondable mode */
-  AppAdvStart(APP_MODE_AUTO_INIT);
-#else
-  /* enter discoverable and bondable mode mode by default */
-  AppSetBondable(TRUE);
-  AppAdvStart(APP_MODE_DISCOVERABLE);
+    DmDevWhiteListAdd(DM_ADDR_PUBLIC, (bdAddr_t){0x02, 0x00, 0x44, 0x8B, 0x05, 0x00});
+    DmDevSetFilterPolicy(DM_FILT_POLICY_MODE_SCAN, HCI_FILT_WHITE_LIST);
+    DmDevSetFilterPolicy(DM_FILT_POLICY_MODE_INIT, HCI_FILT_WHITE_LIST);
 #endif
 }
 
 
+
+/*************************************************************************************************/
+static void testTimerHandler(void)
+{
+    testCb.counter++;
+    
+    if (testCb.counter == 2)
+    {
+#ifdef BTLE_APP_USE_LEGACY_API
+        AppScanStart(scannerMasterCfg.discMode, scannerMasterCfg.scanType, scannerMasterCfg.scanDuration);
+#else /* BTLE_APP_USE_LEGACY_API */
+        AppExtScanStart(
+                        scannerExtMasterScanPhysCfg,
+                        scannerExtMasterCfg.discMode,
+                        scannerExtMasterCfg.scanType,
+                        scannerExtMasterCfg.scanDuration,
+                        scannerExtMasterCfg.scanPeriod);
+#endif /* BTLE_APP_USE_LEGACY_API */
+    }
+    
+    WsfTimerStartMs(&testCb.timer, 1000);
+}
+
 /*************************************************************************************************/
 /*!
  *  \brief  Process messages from the event handler.
@@ -352,88 +319,61 @@ static void bleSetup(bleMsg_t *pMsg)
  *  \return None.
  */
 /*************************************************************************************************/
-static void bleProcMsg(bleMsg_t *pMsg)
+static void scannerProcMsg(dmEvt_t *pMsg)
 {
-  uint8_t uiEvent = APP_UI_NONE;
-
-  switch(pMsg->hdr.event)
-  {
-    case BLE_BATT_TIMER_IND:
-      BasProcMsg(&pMsg->hdr);
-      break;
-
-    case ATTS_HANDLE_VALUE_CNF:
-      BasProcMsg(&pMsg->hdr);
-      break;
-
-    case ATTS_CCC_STATE_IND:
-      bleProcCccState(pMsg);
-      break;
-
-    case DM_RESET_CMPL_IND:
-      DmSecGenerateEccKeyReq();
-      bleSetup(pMsg);
-      uiEvent = APP_UI_RESET_CMPL;
-      break;
-
-    case DM_ADV_START_IND:
-      uiEvent = APP_UI_ADV_START;
-      break;
-
-    case DM_ADV_STOP_IND:
-      uiEvent = APP_UI_ADV_STOP;
-      break;
-
-    case DM_CONN_OPEN_IND:
-      BasProcMsg(&pMsg->hdr);
-      uiEvent = APP_UI_CONN_OPEN;
-      break;
-
-    case DM_CONN_CLOSE_IND:
-      bleClose(pMsg);
-      uiEvent = APP_UI_CONN_CLOSE;
-      break;
-
-    case DM_SEC_PAIR_CMPL_IND:
-      uiEvent = APP_UI_SEC_PAIR_CMPL;
-      break;
-
-    case DM_SEC_PAIR_FAIL_IND:
-      uiEvent = APP_UI_SEC_PAIR_FAIL;
-      break;
-
-    case DM_SEC_ENCRYPT_IND:
-      uiEvent = APP_UI_SEC_ENCRYPT;
-      break;
-
-    case DM_SEC_ENCRYPT_FAIL_IND:
-      uiEvent = APP_UI_SEC_ENCRYPT_FAIL;
-      break;
-
-    case DM_SEC_AUTH_REQ_IND:
-      AppHandlePasskey(&pMsg->dm.authReq);
-      break;
-
-    case DM_SEC_ECC_KEY_IND:
-      DmSecSetEccKey(&pMsg->dm.eccMsg.data.key);
-      break;
-
-    case DM_SEC_COMPARE_IND:
-      AppHandleNumericComparison(&pMsg->dm.cnfInd);
-      break;
-
-    case DM_HW_ERROR_IND:
-      uiEvent = APP_UI_HW_ERROR;
-      break;
-
-    default:
-      break;
-  }
-
-  if (uiEvent != APP_UI_NONE)
-  {
-    AppUiAction(uiEvent);
-  }
+    uint8_t uiEvent = APP_UI_NONE;
+    
+    switch(pMsg->hdr.event)
+    {
+        case DM_RESET_CMPL_IND:
+            DmSecGenerateEccKeyReq();
+            scannerSetup(pMsg);
+            uiEvent = APP_UI_RESET_CMPL;
+            break;
+            
+        case DM_SCAN_START_IND:
+            scannerScanStart(pMsg);
+            uiEvent = APP_UI_SCAN_START;
+            break;
+            
+#ifndef BTLE_APP_IGNORE_EXT_EVENTS
+        case DM_EXT_SCAN_START_IND:
+            scannerScanStart(pMsg);
+            uiEvent = APP_UI_EXT_SCAN_START_IND;
+            break;
+#endif /* BTLE_APP_IGNORE_EXT_EVENTS */
+            
+        case DM_SCAN_STOP_IND:
+            scannerScanStop(pMsg);
+            uiEvent = APP_UI_SCAN_STOP;
+            break;
+            
+#ifndef BTLE_APP_IGNORE_EXT_EVENTS
+        case DM_EXT_SCAN_STOP_IND:
+            scannerScanStop(pMsg);
+            uiEvent = APP_UI_EXT_SCAN_STOP_IND;
+            break;
+#endif /* BTLE_APP_IGNORE_EXT_EVENTS */
+            
+        case DM_SCAN_REPORT_IND:
+            scannerScanReport(pMsg);
+            break;
+            
+#ifndef BTLE_APP_IGNORE_EXT_EVENTS
+        case DM_EXT_SCAN_REPORT_IND:
+            scannerExtScanReport(pMsg);
+            break;
+#endif /* BTLE_APP_IGNORE_EXT_EVENTS */
+            
+        case TEST_TIMER_IND:
+            testTimerHandler();
+            break;
+    }
+    
+    if (uiEvent != APP_UI_NONE)
+    {
+        AppUiAction(uiEvent);
+    }
 }
 
 /*************************************************************************************************/
@@ -445,28 +385,22 @@ static void bleProcMsg(bleMsg_t *pMsg)
  *  \return None.
  */
 /*************************************************************************************************/
-static void BleHandlerInit(void)
+void ScannerHandlerInit(wsfHandlerId_t handlerId)
 {
-  APP_TRACE_INFO0("BleHandlerInit");
-
-  /* store handler ID */
-  bleHandlerId =WsfOsSetNextHandler(BleHandler);
-
-  /* Set configuration pointers */
-  pAppAdvCfg = (appAdvCfg_t *) &bleAdvCfg;
-  pAppSlaveCfg = (appSlaveCfg_t *) &bleSlaveCfg;
-  pAppSecCfg = (appSecCfg_t *) &bleSecCfg;
-  pAppUpdateCfg = (appUpdateCfg_t *) &bleUpdateCfg;
-
-  /* Initialize application framework */
-  AppSlaveInit();
-
-  /* Set stack configuration pointers */
-  pSmpCfg = (smpCfg_t *) &bleSmpCfg;
-  pAttCfg = (attCfg_t *) &bleAttCfg;
-
-  /* initialize battery service server */
-  BasInit(bleHandlerId, (basCfg_t *) &bleBasCfg);
+    APP_TRACE_INFO0("ScannerHandlerInit");
+    
+    /* store handler ID */
+    scannerCb.handlerId = handlerId;
+    
+    /* Set configuration pointers */
+#ifdef BTLE_APP_USE_LEGACY_API
+    pAppMasterCfg = (appMasterCfg_t *) &scannerMasterCfg;
+#else /* BTLE_APP_USE_LEGACY_API */
+    pAppExtMasterCfg = (appExtMasterCfg_t *) &scannerExtMasterCfg;
+#endif /* BTLE_APP_USE_LEGACY_API */
+    
+    /* Initialize application framework */
+    AppMasterInit();
 }
 
 /*************************************************************************************************/
@@ -479,26 +413,38 @@ static void BleHandlerInit(void)
  *  \return None.
  */
 /*************************************************************************************************/
-static void BleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
+void ScannerHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
 {
-  if (pMsg != NULL)
-  {
-    APP_TRACE_INFO1("Ble got evt %d", pMsg->event);
-
-    if (pMsg->event >= DM_CBACK_START && pMsg->event <= DM_CBACK_END)
+    if (pMsg != NULL)
     {
-      /* process advertising and connection-related messages */
-      AppSlaveProcDmMsg((dmEvt_t *) pMsg);
-
-      /* process security-related messages */
-      AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
+        if (pMsg->event != TEST_TIMER_IND)
+        {
+            APP_TRACE_INFO2("Scanner got evt 0x%x, param %u", pMsg->event, pMsg->param);
+        }
+        
+        /* process ATT messages */
+        if (pMsg->event <= ATT_CBACK_END)
+        {
+            /* process discovery-related ATT messages */
+            AppDiscProcAttMsg((attEvt_t *) pMsg);
+        }
+        /* process DM messages */
+        else if (pMsg->event <= DM_CBACK_END)
+        {
+            /* process advertising and connection-related messages */
+            AppMasterProcDmMsg((dmEvt_t *) pMsg);
+            
+            /* process security-related messages */
+            AppMasterSecProcDmMsg((dmEvt_t *) pMsg);
+            
+            /* process discovery-related messages */
+            AppDiscProcDmMsg((dmEvt_t *) pMsg);
+        }
+        
+        /* perform profile and user interface-related operations */
+        scannerProcMsg((dmEvt_t *) pMsg);
     }
-
-    /* perform profile and user interface-related operations */
-    bleProcMsg((bleMsg_t *) pMsg);
-  }
 }
-
 /*************************************************************************************************/
 /*!
  *  \brief  Start the application.
@@ -508,21 +454,10 @@ static void BleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
 /*************************************************************************************************/
 void BleStart(void)
 {
-
-  BleHandlerInit();
-
   /* Register for stack callbacks */
-  DmRegister(bleDmCback);
-  DmConnRegister(DM_CLIENT_ID_APP, bleDmCback);
-  AttRegister(bleAttCback);
-  AttConnRegister(AppServerConnCback);
-  AttsCccRegister(BLE_NUM_CCC_IDX, (attsCccSet_t *) bleCccSet, bleCccCback);
-
-  /* Initialize attribute server database */
-  SvcCoreAddGroup();
-  SvcDisAddGroup(); // Device Information Service
-  SvcBattCbackRegister(BasReadCback, NULL);
-  SvcBattAddGroup();
+  DmRegister(scannerDmCback);
+  
+  // DmConnRegister(DM_CLIENT_ID_APP, bleDmCback);
 
   /* Reset the device */
   DmDevReset();
diff --git a/epicardium/ble/scanner_api.h b/epicardium/ble/scanner_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..54aa5b770c09974b2945db757e8a038bdbec990c
--- /dev/null
+++ b/epicardium/ble/scanner_api.h
@@ -0,0 +1,69 @@
+/*************************************************************************************************/
+/*!
+*  \file
+*
+*  \brief  Proprietary data transfer client sample application.
+*
+*  Copyright (c) 2012-2018 Arm Ltd. All Rights Reserved.
+*  ARM Ltd. confidential and proprietary.
+*
+*  IMPORTANT.  Your use of this file is governed by a Software License Agreement
+*  ("Agreement") that must be accepted in order to download or otherwise receive a
+*  copy of this file.  You may not use or copy this file for any purpose other than
+*  as described in the Agreement.  If you do not agree to all of the terms of the
+*  Agreement do not use this file and delete all copies in your possession or control;
+*  if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
+*  to any use, copying or further distribution of this software.
+*/
+/*************************************************************************************************/
+#ifndef SCANNER_API_H
+#define SCANNER_API_H
+
+#include "wsf_os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**************************************************************************************************
+Function Declarations
+**************************************************************************************************/
+/*************************************************************************************************/
+/*!
+*  \brief  Start the application.
+*
+*  \return None.
+*/
+/*************************************************************************************************/
+void ScannerStart(void);
+
+/*************************************************************************************************/
+/*!
+*  \brief  Application handler init function called during system initialization.
+*
+*  \param  handlerID  WSF handler ID for App.
+*
+*  \return None.
+*/
+/*************************************************************************************************/
+void ScannerHandlerInit(wsfHandlerId_t handlerId);
+
+
+/*************************************************************************************************/
+/*!
+*  \brief  WSF event handler for the application.
+*
+*  \param  event   WSF event mask.
+*  \param  pMsg    WSF message.
+*
+*  \return None.
+*/
+/*************************************************************************************************/
+void ScannerHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* SCANNER_API_H */
+
diff --git a/epicardium/ble/stack.c b/epicardium/ble/stack.c
index 690d1cb1447c05e841f157b4edb494ba2241460e..2e858dfa6e712050c4a8b5d3bc83fb5050d9569b 100644
--- a/epicardium/ble/stack.c
+++ b/epicardium/ble/stack.c
@@ -2,7 +2,7 @@
 /*!
  *  \file
  *
- *  \brief  Stack initialization
+ *  \brief  Stack initialization for scanner.
  *
  *  Copyright (c) 2016-2017 ARM Ltd. All Rights Reserved.
  *  ARM Ltd. confidential and proprietary.
@@ -17,26 +17,12 @@
  */
 /*************************************************************************************************/
 
-/*
- * This file initializes the different components of the whole BLE stack. This inlucdes link level,
- * HCI, security, etc...
- *
- * This file has been copied from lib/sdk/Applications/EvKitExamples/BLE_fit/stack_fit.c
- *
- * NOTE: Different stack_*.c files in the SDK initialize different components. We have to
- * be very carefull to intitialize all needed components here. Think e.g. SecRandInit() ...
- *
- * Many components are related to the role of the device. Different components need to be
- * initialized for central and peripheral roles.
- */
-/* clang-format off */
-/* clang-formet turned off for easier diffing against orginal file */
 #include <stdio.h>
 #include <string.h>
 #include "wsf_types.h"
 #include "wsf_os.h"
 #include "util/bstream.h"
-#include "ble_api.h"
+#include "scanner_api.h"
 #include "hci_handler.h"
 #include "dm_handler.h"
 #include "l2c_handler.h"
@@ -51,11 +37,9 @@
 #include "sec_api.h"
 #include "ll_init_api.h"
 
-/* TODO: card10: Where does this number come from? Is there any documentation? */
 #define LL_IMPL_REV             0x2303
 
-/* TODO: card10: Where does this number come from? Is there any documentation? */
-#define LL_MEMORY_FOOTPRINT     0xC152
+#define LL_MEMORY_FOOTPRINT     0xc152
 
 uint8_t LlMem[LL_MEMORY_FOOTPRINT];
 
@@ -65,18 +49,18 @@ const LlRtCfg_t _ll_cfg = {
     /*implRev*/                 LL_IMPL_REV,
     /*btVer*/                   LL_VER_BT_CORE_SPEC_5_0,
     /*_align32 */               0, // padding for alignment
-
+    
     /* Advertiser */
     /*maxAdvSets*/              4, // 4 Extended Advertising Sets
     /*maxAdvReports*/           8,
     /*maxExtAdvDataLen*/        LL_MAX_ADV_DATA_LEN,
     /*defExtAdvDataFrag*/       64,
     /*auxDelayUsec*/            0,
-
+    
     /* Scanner */
     /*maxScanReqRcvdEvt*/       4,
     /*maxExtScanDataLen*/       LL_MAX_ADV_DATA_LEN,
-
+    
     /* Connection */
     /*maxConn*/                 2,
     /*numTxBufs*/               16,
@@ -84,10 +68,10 @@ const LlRtCfg_t _ll_cfg = {
     /*maxAclLen*/               512,
     /*defTxPwrLvl*/             0,
     /*ceJitterUsec*/            0,
-
+    
     /* DTM */
     /*dtmRxSyncMs*/             10000,
-
+    
     /* PHY */
     /*phy2mSup*/                TRUE,
     /*phyCodedSup*/             TRUE,
@@ -109,81 +93,82 @@ const BbRtCfg_t _bb_cfg = {
  *  \return     None.
  */
 /*************************************************************************************************/
-void StackInit(void)
+void StackInitScanner(void)
 {
-  wsfHandlerId_t handlerId;
-
-/* card10: We do not use the SDMA HCI at the moment. The block below is not compiled. */
+    wsfHandlerId_t handlerId;
+    
 #ifndef ENABLE_SDMA
-  uint32_t memUsed;
-
-  /* Initialize link layer. */
-  LlInitRtCfg_t ll_init_cfg =
-  {
-      .pBbRtCfg     = &_bb_cfg,
-      .wlSizeCfg    = 4,
-      .rlSizeCfg    = 4,
-      .plSizeCfg    = 4,
-      .pLlRtCfg     = &_ll_cfg,
-      .pFreeMem     = LlMem,
-      .freeMemAvail = LL_MEMORY_FOOTPRINT
-  };
-
-#ifdef DATS_APP_USE_LEGACY_API
-  memUsed = LlInitControllerExtInit(&ll_init_cfg);
-#else /* DATS_APP_USE_LEGACY_API */
-  memUsed = LlInitControllerExtInit(&ll_init_cfg);
-#endif /* DATS_APP_USE_LEGACY_API */
-  if(memUsed != LL_MEMORY_FOOTPRINT)
-  {
-      printf("Controller memory mismatch 0x%x != 0x%x\n", (unsigned int)memUsed, 
-          (unsigned int)LL_MEMORY_FOOTPRINT);
-  }
+    uint32_t memUsed;
+    
+    /* Initialize link layer. */
+    LlInitRtCfg_t ll_init_cfg =
+    {
+        .pBbRtCfg     = &_bb_cfg,
+        .wlSizeCfg    = 4,
+        .rlSizeCfg    = 4,
+        .plSizeCfg    = 4,
+        .pLlRtCfg     = &_ll_cfg,
+        .pFreeMem     = LlMem,
+        .freeMemAvail = LL_MEMORY_FOOTPRINT
+    };
+    
+    memUsed = LlInitControllerExtInit(&ll_init_cfg);
+    // memUsed = LlInitControllerInit(&ll_init_cfg);
+    if(memUsed != LL_MEMORY_FOOTPRINT)
+    {
+        printf("mem_used: 0x%x LL_MEMORY_FOOTPRINT: 0x%x\n", memUsed,
+               LL_MEMORY_FOOTPRINT);
+    }
 #endif
-
-
-  /* card10:
-   * These calls register a queue for callbacks in the OS abstraction
-   * and then pass a handle down to modules which uses them to
-   * internally handle callbacks.
-   *
-   * No idea why the modules don't call WsfOsSetNextHandler()
-   * internally ... */
-  handlerId = WsfOsSetNextHandler(HciHandler);
-  HciHandlerInit(handlerId);
-
-  SecInit();
-  SecAesInit();
-  SecCmacInit();
-  SecEccInit();
-
-  handlerId = WsfOsSetNextHandler(DmHandler);
-  DmDevVsInit(0);
-  DmAdvInit();
-  DmConnInit();
-  DmConnSlaveInit();
-  DmSecInit();
-  DmSecLescInit();
-  DmPrivInit();
-  DmPhyInit();
-  DmHandlerInit(handlerId);
-
-  handlerId = WsfOsSetNextHandler(L2cSlaveHandler);
-  L2cSlaveHandlerInit(handlerId);
-  L2cInit();
-  L2cSlaveInit();
-
-  handlerId = WsfOsSetNextHandler(AttHandler);
-  AttHandlerInit(handlerId);
-  AttsInit();
-  AttsIndInit();
-
-  handlerId = WsfOsSetNextHandler(SmpHandler);
-  SmpHandlerInit(handlerId);
-  SmprInit();
-  SmprScInit();
-
-  /*TODO card10: Probably want to adjust this */
-  HciSetMaxRxAclLen(100);
+    
+    SecInit();
+    SecRandInit();
+    SecAesInit();
+    SecCmacInit();
+    SecEccInit();
+    
+    handlerId = WsfOsSetNextHandler(HciHandler);
+    HciHandlerInit(handlerId);
+    
+    handlerId = WsfOsSetNextHandler(DmHandler);
+    DmDevVsInit(0);
+    DmDevPrivInit();
+#ifdef BTLE_APP_USE_LEGACY_API
+    DmScanInit();
+    DmConnInit();
+    DmConnMasterInit();
+#else /* BTLE_APP_USE_LEGACY_API */
+    DmExtScanInit();
+    DmConnInit();
+    DmExtConnMasterInit();
+#endif /* BTLE_APP_USE_LEGACY_API */
+    DmSecInit();
+    DmPhyInit();
+    DmSecLescInit();
+    DmPrivInit();
+    DmHandlerInit(handlerId);
+    
+    L2cInit();
+    L2cMasterInit();
+    
+    handlerId = WsfOsSetNextHandler(AttHandler);
+    AttHandlerInit(handlerId);
+    AttsInit();
+    AttsIndInit();
+    AttcInit();
+    AttsSignInit();
+    
+    handlerId = WsfOsSetNextHandler(SmpHandler);
+    SmpHandlerInit(handlerId);
+    SmpiInit();
+    SmpiScInit();
+    HciSetMaxRxAclLen(100);
+    
+    /*
+    handlerId = WsfOsSetNextHandler(AppHandler);
+    AppHandlerInit(handlerId);
+    */
+    
+    handlerId = WsfOsSetNextHandler(ScannerHandler);
+    ScannerHandlerInit(handlerId);
 }
-/* clang-format off */