From 92b5e2d950b534f48899a710cc8e6f5cab9fa038 Mon Sep 17 00:00:00 2001
From: David <stierint@hotmail.com>
Date: Wed, 19 Aug 2020 22:08:28 -0400
Subject: [PATCH] two uwbs working with TDMA

---
 DecaRanging.coproj                        |   44 +-
 src/application/application_definitions.h |  488 ++++
 src/application/comm_scheduler.c          |   82 +-
 src/application/comm_scheduler.h          |   50 +-
 src/application/dw_main.c                 |   88 +-
 src/application/instance.c                | 1682 ++++++++++----
 src/application/instance.h                |  447 +---
 src/application/instance_common.c         | 1107 +++++----
 src/application/rx_scheduler.c            |    2 +-
 src/application/tdma_handler.c            | 2566 +++++++++++++++++++++
 src/application/tdma_handler.h            |  119 +
 src/application/tdma_scheduler.c          |  214 ++
 src/application/tdma_scheduler.h          |   62 +
 src/application/tx_scheduler.c            |   74 +-
 src/application/tx_scheduler.h            |   53 +-
 src/decadriver/deca_device.c              |   96 +-
 src/liblist/inc/llist.h                   |  267 ---
 src/liblist/src/Complex.c                 |    9 -
 src/liblist/src/Complex.h                 |    7 -
 src/liblist/src/llist.c                   |  676 ------
 src/usb/deca_usb.c                        |    4 +-
 21 files changed, 5483 insertions(+), 2654 deletions(-)
 create mode 100644 src/application/application_definitions.h
 create mode 100644 src/application/tdma_handler.c
 create mode 100644 src/application/tdma_handler.h
 create mode 100644 src/application/tdma_scheduler.c
 create mode 100644 src/application/tdma_scheduler.h
 delete mode 100644 src/liblist/inc/llist.h
 delete mode 100644 src/liblist/src/Complex.c
 delete mode 100644 src/liblist/src/Complex.h
 delete mode 100644 src/liblist/src/llist.c

diff --git a/DecaRanging.coproj b/DecaRanging.coproj
index 0e90857..983056d 100644
--- a/DecaRanging.coproj
+++ b/DecaRanging.coproj
@@ -4,7 +4,7 @@
     <Device manufacturerId="9" manufacturerName="ST" chipId="334" chipName="STM32F105RC" boardId="" boardName=""/>
     <BuildOption>
       <Compile>
-        <Option name="OptimizationLevel" value="0"/>
+        <Option name="OptimizationLevel" value="4"/>
         <Option name="UseFPU" value="0"/>
         <Option name="UserEditCompiler" value="-ffunction-sections; -fdata-sections; -c; -fmessage-length=0;"/>
         <Includepaths>
@@ -89,15 +89,14 @@
   <Components path="./"/>
   <Files>
     <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_ioreq.h" type="1"/>
-    <File name="src/application/uwb_select.h" path="src/application/uwb_select.h" type="1"/>
-    <File name="src/liblist/inc/llist.h" path="src/liblist/inc/llist.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_fsmc.h" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_usr.h" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Core" path="" type="2"/>
     <File name="src/usb/usbd_desc.c" path="src/usb/usbd_desc.c" type="1"/>
     <File name="src" path="" type="2"/>
-    <File name="Libraries/CMSIS" path="" type="2"/>
     <File name="Libraries/STM32_USB_Device_Library/Class/cdc" path="" type="2"/>
+    <File name="Libraries/CMSIS" path="" type="2"/>
+    <File name="src/application/comm_scheduler.c" path="src/application/comm_scheduler.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dac.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dac.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_hcd_int.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_hcd_int.h" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Class/cdc/src" path="" type="2"/>
@@ -106,24 +105,23 @@
     <File name="src/platform/deca_spi.h" path="src/platform/deca_spi.h" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c" path="Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c" path="Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c" type="1"/>
-    <File name="Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h" path="Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h" type="1"/>
     <File name="src/usb/usbd_desc.h" path="src/usb/usbd_desc.h" type="1"/>
+    <File name="Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h" path="Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h" type="1"/>
     <File name="src/platform/deca_spi.c" path="src/platform/deca_spi.c" type="1"/>
     <File name="src/usb" path="" type="2"/>
     <File name="src/decadriver/deca_version.h" path="src/decadriver/deca_version.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c" type="1"/>
-    <File name="src/liblist/inc" path="" type="2"/>
-    <File name="src/application/instance.c" path="src/application/instance.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c" type="1"/>
+    <File name="src/application/instance.c" path="src/application/instance.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c" type="1"/>
     <File name="src/decadriver/deca_device_api.h" path="src/decadriver/deca_device_api.h" type="1"/>
     <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x" path="" type="2"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h" type="1"/>
+    <File name="src/application/tdma_handler.h" path="src/application/tdma_handler.h" type="1"/>
     <File name="src/compiler/compiler.h" path="src/compiler/compiler.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver" path="" type="2"/>
-    <File name="src/application/uwb_select.c" path="src/application/uwb_select.c" type="1"/>
     <File name="src/platform/deca_mutex.c" path="src/platform/deca_mutex.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c" type="1"/>
     <File name="src/platform/port.h" path="src/platform/port.h" type="1"/>
@@ -132,32 +130,32 @@
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_rcc.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_can.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_can.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_sdio.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_sdio.h" type="1"/>
-    <File name="src/application/rx_scheduler.h" path="src/application/rx_scheduler.h" type="1"/>
+    <File name="src/application/tdma_handler.c" path="src/application/tdma_handler.c" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/src/usb_hcd_int.c" path="Libraries/STM32_USB_OTG_Driver/src/usb_hcd_int.c" type="1"/>
     <File name="src/platform/port.c" path="src/platform/port.c" type="1"/>
-    <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h" type="1"/>
+    <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h" type="1"/>
     <File name="src/decadriver/deca_device.c" path="src/decadriver/deca_device.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c" type="1"/>
+    <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c" type="1"/>
-    <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c" type="1"/>
     <File name="src/usb/usb_conf.h" path="src/usb/usb_conf.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_otg.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_otg.h" type="1"/>
-    <File name="Libraries/STM32_USB_OTG_Driver/llist.c" path="src/liblist/src/llist.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c" path="Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c" type="1"/>
-    <File name="src/application/rx_scheduler.c" path="src/application/rx_scheduler.c" type="1"/>
     <File name="src/usb/usbd_conf.h" path="src/usb/usbd_conf.h" type="1"/>
+    <File name="src/application/application_definitions.h" path="src/application/application_definitions.h" type="1"/>
     <File name="src/usb/deca_usb.c" path="src/usb/deca_usb.c" type="1"/>
     <File name="src/platform/deca_range_tables.c" path="src/platform/deca_range_tables.c" type="1"/>
+    <File name="src/application/lib.h" path="src/application/lib.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/src" path="" type="2"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c" type="1"/>
     <File name="src/application/instance_common.c" path="src/application/instance_common.c" type="1"/>
-    <File name="src/decadriver/deca_params_init.c" path="src/decadriver/deca_params_init.c" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Core/inc" path="" type="2"/>
+    <File name="src/decadriver/deca_params_init.c" path="src/decadriver/deca_params_init.c" type="1"/>
     <File name="src/application" path="" type="2"/>
     <File name="src/application/instance_calib.c" path="src/application/instance_calib.c" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_dcd.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_dcd.h" type="1"/>
@@ -167,26 +165,24 @@
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/misc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/misc.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c" path="Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c" type="1"/>
-    <File name="src/liblist/src" path="" type="2"/>
     <File name="src/application/main.c" path="src/main.c" type="1"/>
     <File name="src/platform/deca_sleep.c" path="src/platform/deca_sleep.c" type="1"/>
-    <File name="Libraries/CMSIS/CM3/CoreSupport" path="" type="2"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_defines.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_defines.h" type="1"/>
+    <File name="Libraries/CMSIS/CM3/CoreSupport" path="" type="2"/>
     <File name="Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c" path="Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c" type="1"/>
     <File name="src/compiler" path="" type="2"/>
     <File name="src/decadriver/deca_param_types.h" path="src/decadriver/deca_param_types.h" type="1"/>
     <File name="src/usb/deca_usb_bsp_evk1000.c" path="src/usb/deca_usb_bsp_evk1000.c" type="1"/>
     <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/startup_stm32f10x_cl.S" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/startup_stm32f10x_cl.S" type="1"/>
-    <File name="src/application/tx_scheduler.h" path="src/application/tx_scheduler.h" type="1"/>
-    <File name="src/platform/stm32f10x_conf.h" path="src/platform/stm32f10x_conf.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h" type="1"/>
+    <File name="src/platform/stm32f10x_conf.h" path="src/platform/stm32f10x_conf.h" type="1"/>
     <File name="Libraries/CMSIS/CM3" path="" type="2"/>
     <File name="Libraries" path="" type="2"/>
     <File name="src/decadriver/deca_types.h" path="src/decadriver/deca_types.h" type="1"/>
     <File name="src/usb/deca_usb.h" path="src/usb/deca_usb.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc" path="" type="2"/>
-    <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h" type="1"/>
+    <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h" type="1"/>
     <File name="src/platform/stm32f10x_it.c" path="src/platform/stm32f10x_it.c" type="1"/>
     <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c" type="1"/>
@@ -198,15 +194,15 @@
     <File name="Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c" path="Libraries/STM32_USB_Device_Library/Core/src/usbd_core.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_exti.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_regs.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_regs.h" type="1"/>
-    <File name="src/liblist/src/llist.c" path="src/liblist/src/llist.c" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library" path="" type="2"/>
     <File name="Libraries/STM32_USB_Device_Library/Class" path="" type="2"/>
     <File name="Libraries/CMSIS/CM3/CoreSupport/core_cm3.c" path="Libraries/CMSIS/CM3/CoreSupport/core_cm3.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_cec.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_cec.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver" path="" type="2"/>
+    <File name="src/application/comm_scheduler.h" path="src/application/comm_scheduler.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_hcd.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_hcd.h" type="1"/>
-    <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h" type="1"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc" path="" type="2"/>
+    <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_core.h" type="1"/>
     <File name="Libraries/CMSIS/CM3/DeviceSupport" path="" type="2"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dac.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dac.c" type="1"/>
@@ -216,8 +212,8 @@
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_usart.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_tim.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_tim.h" type="1"/>
     <File name="Libraries/STM32_USB_Device_Library/Class/cdc/inc" path="" type="2"/>
-    <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup" path="" type="2"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/misc.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/misc.h" type="1"/>
+    <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup" path="" type="2"/>
     <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_core.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_core.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c" type="1"/>
     <File name="src/application/dw_main.c" path="src/application/dw_main.c" type="1"/>
@@ -225,9 +221,8 @@
     <File name="src/platform" path="" type="2"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h" type="1"/>
-    <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src" path="" type="2"/>
-    <File name="src/liblist" path="" type="2"/>
+    <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h" type="1"/>
     <File name="Libraries/CMSIS/CM3/DeviceSupport/ST" path="" type="2"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dbgmcu.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dbgmcu.c" type="1"/>
     <File name="src/decadriver/deca_regs.h" path="src/decadriver/deca_regs.h" type="1"/>
@@ -235,6 +230,5 @@
     <File name="src/usb/usbd_usr.c" path="src/usb/usbd_usr.c" type="1"/>
     <File name="src/application/instance.h" path="src/application/instance.h" type="1"/>
     <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_gpio.h" type="1"/>
-    <File name="src/application/tx_scheduler.c" path="src/application/tx_scheduler.c" type="1"/>
   </Files>
 </Project>
\ No newline at end of file
diff --git a/src/application/application_definitions.h b/src/application/application_definitions.h
new file mode 100644
index 0000000..da3d693
--- /dev/null
+++ b/src/application/application_definitions.h
@@ -0,0 +1,488 @@
+#ifndef APPLICATION_DEFINITIONS_H_
+#define APPLICATION_DEFINITIONS_H_
+
+#include "port.h"
+#include "deca_types.h"
+#include "deca_device_api.h"
+
+/******************************************************************************************************************
+********************* NOTES on Decaranging EVK1000 application features/options ***********************************************************
+*******************************************************************************************************************/
+#define DEEP_SLEEP (0) //To enable deep-sleep set this to 1
+//DEEP_SLEEP mode can be used, for example, by a Tag instance to put the DW1000 into low-power deep-sleep mode
+
+#define CORRECT_RANGE_BIAS  (1)     // Compensate for small bias due to uneven accumulator growth at close up high power
+
+
+
+/******************************************************************************************************************
+*******************************************************************************************************************
+*******************************************************************************************************************/
+
+#define NUM_INST            1
+#define SPEED_OF_LIGHT      (299704644.54) //(299702547.0)     // in m/s in air
+#define MASK_40BIT			(0x00FFFFFFFFFF)  // DW1000 counter is 40 bits
+#define MASK_TXDTS			(0x00FFFFFFFE00)  //The TX timestamp will snap to 8 ns resolution - mask lower 9 bits.
+#define SYS_MASK_VAL        (DWT_INT_TFRS | DWT_INT_RFCG | DWT_INT_RXOVRR | DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO)
+#define DELAY_CALIB (0)                     // when set to 1 - the LCD display will show information used for TX/RX delay calibration
+
+#define SET_TXRX_DELAY (0)                  //when set to 1 - the DW1000 RX and TX delays are set to the TX_DELAY and RX_DELAY defines
+#define TX_ANT_DELAY                0
+#define RX_ANT_DELAY                0
+
+#define USING_64BIT_ADDR (0)                  //when set to 0 - the DecaRanging application will use 16-bit addresses
+#define USING_LCD (1)                         //when set to 0 - the DecaRanging application will not use the LCD display
+
+//! callback events
+#define DWT_SIG_RX_NOERR            0
+#define DWT_SIG_TX_DONE             1       // Frame has been sent
+#define DWT_SIG_RX_OKAY             2       // Frame Received with Good CRC
+#define DWT_SIG_RX_ERROR            3       // Frame Received but CRC is wrong
+#define DWT_SIG_RX_TIMEOUT          4       // Timeout on receive has elapsed
+#define DWT_SIG_TX_AA_DONE          6       // ACK frame has been sent (as a result of auto-ACK)
+#define DWT_SIG_RX_BLINK			7		// Received ISO EUI 64 blink message
+#define DWT_SIG_RX_PHR_ERROR        8       // Error found in PHY Header
+#define DWT_SIG_RX_SYNCLOSS         9       // Un-recoverable error in Reed Solomon Decoder
+#define DWT_SIG_RX_SFDTIMEOUT       10      // Saw preamble but got no SFD within configured time
+#define DWT_SIG_RX_PTOTIMEOUT       11      // Got preamble detection timeout (no preamble detected)
+
+#define DWT_SIG_TX_PENDING          12      // TX is pending
+#define DWT_SIG_TX_ERROR            13      // TX failed
+#define DWT_SIG_RX_PENDING          14      // RX has been re-enabled
+#define DWT_SIG_DW_IDLE             15      // DW radio is in IDLE (no TX or RX pending)
+
+#define SIG_RX_UNKNOWN			99		// Received an unknown frame
+
+// Existing frames type in ranging process.
+enum
+{
+    BLINK = 0,
+    RNG_INIT,
+    POLL,
+    RESP,
+    FINAL,
+    INF,
+    FRAME_TYPE_NB //TODO add in RNG_REPORT? would be useful in calculating how long a frame slot should be... if so, dont forget to update the init_timings function...
+};
+
+//TWO WAY RANGING function codes
+#define RTLS_DEMO_MSG_RNG_INIT              (0x20)          // Ranging initiation message
+#define RTLS_DEMO_MSG_TAG_POLL              (0x21)          // Tag poll message
+#define RTLS_DEMO_MSG_ANCH_RESP             (0x10)          // Anchor response to poll
+#define RTLS_DEMO_MSG_TAG_FINAL             (0x29)          // Tag final massage back to Anchor (0x29 because of 5 byte timestamps needed for PC app)
+#define RTLS_DEMO_MSG_INF_REG              	(0x13)          // TDMA coordination info packet
+#define RTLS_DEMO_MSG_INF_INIT              (0x14)          // TDMA coordination info packet
+#define RTLS_DEMO_MSG_INF_SUG              	(0x15)          // TDMA coordination info packet
+#define RTLS_DEMO_MSG_INF_UPDATE            (0x16)          // TDMA coordination info packet
+#define RTLS_DEMO_MSG_RNG_REPORT            (0x11)			// Report of calculated range back to the Tag
+
+//lengths including the Decaranging Message Function Code byte
+#define TAG_POLL_MSG_LEN                    1				// FunctionCode(1),
+#define ANCH_RESPONSE_MSG_LEN               15               // FunctionCode(1), RespOption (1), OptionParam(2), Number of Tags(1), Measured_TOF_Time(6), Time Till next window reserved for catching a blink message (4)
+#define TAG_FINAL_MSG_LEN                   16              // FunctionCode(1), Poll_TxTime(5), Resp_RxTime(5), Final_TxTime(5)
+#define RANGINGINIT_MSG_LEN					7				// FunctionCode(1), Tag Address (2), Response Time (2) * 2
+#define RNG_REPORT_MSG_LEN				    7			// FunctionCode(1), time of flight (6)
+
+#define MAX_MAC_MSG_DATA_LEN                (TAG_FINAL_MSG_LEN) //max message len of the above
+
+#define BROADCAST_ADDRESS           0xFFFF					//address for broadcasting messages to all UWBs the network
+
+#define STANDARD_FRAME_SIZE         127
+#define EXTENDED_FRAME_SIZE			1023
+
+#define ADDR_BYTE_SIZE_L            (8)
+#define ADDR_BYTE_SIZE_S            (2)
+
+#define FRAME_CONTROL_BYTES         2
+#define FRAME_SEQ_NUM_BYTES         1
+#define FRAME_PANID                 2
+#define FRAME_CRC					2
+#define FRAME_SOURCE_ADDRESS_S        (ADDR_BYTE_SIZE_S)
+#define FRAME_DEST_ADDRESS_S          (ADDR_BYTE_SIZE_S)
+#define FRAME_SOURCE_ADDRESS_L        (ADDR_BYTE_SIZE_L)
+#define FRAME_DEST_ADDRESS_L          (ADDR_BYTE_SIZE_L)
+#define FRAME_CTRLP					(FRAME_CONTROL_BYTES + FRAME_SEQ_NUM_BYTES + FRAME_PANID) //5
+#define FRAME_CRTL_AND_ADDRESS_L    (FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_L + FRAME_CTRLP) //21 bytes for 64-bit addresses)
+#define FRAME_CRTL_AND_ADDRESS_S    (FRAME_DEST_ADDRESS_S + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //9 bytes for 16-bit addresses)
+#define FRAME_CRTL_AND_ADDRESS_LS	(FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //15 bytes for 1 16-bit address and 1 64-bit address)
+//#define MAX_USER_PAYLOAD_STRING_LL     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 21 - 16 - 2 = 88
+//#define MAX_USER_PAYLOAD_STRING_SS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 9 - 16 - 2 = 100
+//#define MAX_USER_PAYLOAD_STRING_LS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 15 - 16 - 2 = 94
+#define MAX_USER_PAYLOAD_STRING_LL     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-FRAME_CRC) //127 - 21 - 2 = 104
+#define MAX_USER_PAYLOAD_STRING_SS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-FRAME_CRC) //127 - 9 - 2 = 116
+#define MAX_USER_PAYLOAD_STRING_LS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-FRAME_CRC) //127 - 15 - 2 = 110
+#define MAX_EXTENDED_USER_PAYLOAD_STRING_LL     (EXTENDED_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-FRAME_CRC) //1023 - 21 - 2 = 100
+#define MAX_EXTENDED_USER_PAYLOAD_STRING_SS     (EXTENDED_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-FRAME_CRC) //1023 - 9 - 2 = 112
+#define MAX_EXTENDED_USER_PAYLOAD_STRING_LS     (EXTENDED_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-FRAME_CRC) //1023 - 15 - 2 = 1006
+
+//NOTE: the user payload assumes that there are only 88 "free" bytes to be used for the user message (it does not scale according to the addressing modes)
+#define MAX_USER_PAYLOAD_STRING	MAX_USER_PAYLOAD_STRING_LL
+
+// Total frame lengths.
+#if (USING_64BIT_ADDR == 1)
+    #define RNG_INIT_FRAME_LEN_BYTES (RANGINGINIT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
+    #define POLL_FRAME_LEN_BYTES (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
+    #define RESP_FRAME_LEN_BYTES (ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
+    #define FINAL_FRAME_LEN_BYTES (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
+#else
+    #define RNG_INIT_FRAME_LEN_BYTES (RANGINGINIT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC)
+    #define POLL_FRAME_LEN_BYTES (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
+    #define RESP_FRAME_LEN_BYTES (ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
+    #define FINAL_FRAME_LEN_BYTES (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
+#endif
+
+#define BLINK_FRAME_CONTROL_BYTES       (1)
+#define BLINK_FRAME_SEQ_NUM_BYTES       (1)
+#define BLINK_FRAME_CRC					(FRAME_CRC)
+#define BLINK_FRAME_SOURCE_ADDRESS      (ADDR_BYTE_SIZE_L)
+#define BLINK_FRAME_CTRLP				(BLINK_FRAME_CONTROL_BYTES + BLINK_FRAME_SEQ_NUM_BYTES) //2
+#define BLINK_FRAME_CRTL_AND_ADDRESS    (BLINK_FRAME_SOURCE_ADDRESS + BLINK_FRAME_CTRLP) //10 bytes
+#define BLINK_FRAME_LEN_BYTES           (BLINK_FRAME_CRTL_AND_ADDRESS + BLINK_FRAME_CRC)
+
+#define UWB_LIST_SIZE				    (10)	//maximum number of UWBs to range with (valid options are 0 through 253)//TODO check what works based on data sizes needed for INF packets and 16 or 64 bit addres
+#define UWB_COMM_TIMEOUT                3000    //ms	//TODO maybe make this a function of other defines?
+
+//UWB_LIST entry types
+#define UWB_LIST_SELF					0 //entry for self in list
+#define UWB_LIST_NEIGHBOR				1 //uwb in list that is active, in range, and are slotted to range with
+#define UWB_LIST_HIDDEN					2 //uwb in list that is active, out of range, and a neighbor is slotted to range with
+#define UWB_LIST_TWICE_HIDDEN			3 //uwb in list that is active, out of range, and a hidden neighbor is slotted to range with
+#define UWB_LIST_INACTIVE               4 //uwb in list that is not active (could have previously been neighbor, hidden, or twice hidden)
+
+#define BLINK_SLEEP_DELAY					0     //ms //how long the tag should sleep after blinking
+#define POLL_SLEEP_DELAY					25     //ms //how long the tag should sleep after ranging
+
+
+
+#define IMMEDIATE_RESPONSE (1)
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// NOTE: the maximum RX timeout is ~ 65ms
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+#define INST_DONE_WAIT_FOR_NEXT_EVENT   1   //this signifies that the current event has been processed and instance is ready for next one
+#define INST_DONE_WAIT_FOR_NEXT_EVENT_TO    2   //this signifies that the current event has been processed and that instance is waiting for next one with a timeout
+                                        //which will trigger if no event coming in specified time
+#define INST_NOT_DONE_YET               0   //this signifies that the instance is still processing the current event
+
+// Function code byte offset (valid for all message types).
+#define FCODE                               0               // Function code is 1st byte of messageData
+
+//INF message byte offsets
+#define TDMA_TSFS                           1				// offset to put time since TDMA frame start in the INF message
+#define TDMA_NUMN							5				// offset to put the number of this UWB's neighbors in the INF message
+#define TDMA_NUMH							6				// offset to put the number of this UWB's hidden neighbors in the INF message
+#define TDMA_FRAMELENGTH                    7				// offset to put this UWB's TDMA framelength in the INF message
+#define TDMA_NUMS							8				// offset to put the number of this UWB's TDMA slot assignments in the INF message
+
+
+// Final message byte offsets.
+#define PTXT                                1
+#define RRXT                                6
+#define FTXT                                11
+
+
+// Anchor response byte offsets.
+#define RES_R1                              1               // Response option octet 0x02 (1),
+#define RES_R2                              2               // Response option parameter 0x00 (1) - used to notify Tag that the report is coming
+#define RES_R3                              3               // Response option parameter 0x00 (1),
+#define NTAG                                4               // Offset to put number of active TAGs in the report message. (1 byte)
+#define TOFR                                5               // Offset to put ToF values in the report message.			  (6 bytes)
+#define TIME_TILL						    11				// Offset to put time until next RX_ACCEPT in the report message (4 bytes)
+
+// Ranging init message byte offsets. Composed of tag short address, anchor
+// response delay and tag response delay.
+#define RNG_INIT_TAG_SHORT_ADDR_LO 1
+#define RNG_INIT_TAG_SHORT_ADDR_HI 2
+#define RNG_INIT_ANC_RESP_DLY_LO 3
+#define RNG_INIT_ANC_RESP_DLY_HI 4
+#define RNG_INIT_TAG_RESP_DLY_LO 5
+#define RNG_INIT_TAG_RESP_DLY_HI 6
+
+// Response delay values coded in ranging init message.
+// This is a bitfield composed of:
+//   - bits 0 to 14: value
+//   - bit 15: unit
+#define RESP_DLY_VAL_SHIFT 0
+#define RESP_DLY_VAL_MASK 0x7FFF
+#define RESP_DLY_UNIT_SHIFT 15
+#define RESP_DLY_UNIT_MASK 0x8000
+
+// Response time possible units: microseconds or milliseconds.
+#define RESP_DLY_UNIT_US 0
+#define RESP_DLY_UNIT_MS 1
+
+// Response delays types present in ranging init message.
+enum
+{
+    RESP_DLY_ANC = 0,
+    RESP_DLY_TAG,
+    RESP_DLY_NB
+};
+
+// Convert microseconds to symbols, float version.
+// param  x  value in microseconds
+// return  value in symbols.
+#define US_TO_SY(x) ((x) / 1.0256)
+
+// Convert microseconds to symbols, integer version.
+// param  x  value in microseconds
+// return  value in symbols.
+// /!\ Due to the the multiplication by 10000, be careful about potential
+// values and type for x to avoid overflows.
+#define US_TO_SY_INT(x) (((x) * 10000) / 10256)
+
+// Minimum delay between reception and following transmission.
+#define RX_TO_TX_TIME_US 150 //TODO tune again (150)
+#define RXTOTXTIME          ((int)(50.0 / 1.0256)) //e.g. Poll RX to Response TX time
+
+// Default anchor turn-around time: has to be RX_TO_TX_TIME_US when using
+// immediate response, cannot be less than 170 us when not.
+#define ANC_TURN_AROUND_TIME_US RX_TO_TX_TIME_US
+#if (IMMEDIATE_RESPONSE == 1) && (ANC_TURN_AROUND_TIME_US != RX_TO_TX_TIME_US)
+    #error "When using immediate response, anchor turn-around time has to be equal to RX to TX time!"
+#endif
+// Default tag turn-around time: cannot be less than 300 us. Defined as 500 us
+// so that the tag is not transmitting more than one frame by millisecond (for
+// power management purpose).
+#define TAG_TURN_AROUND_TIME_US 1500 //TODO tune again!!! (300)
+
+// "Long" response delays value. Over this limit, special processes must be
+// applied.
+#define LONG_RESP_DLY_LIMIT_US 25000
+
+// Delay between blink reception and ranging init message. This is the same for
+// all modes.
+#define RNG_INIT_REPLY_DLY_MS (20)
+
+#define MAX(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a > _b ? _a : _b; })
+
+
+#define BLINK_DURATION_MS						RNG_INIT_REPLY_DLY_MS + 1
+#define RANGE_DURATION_MS						MAX(18, POLL_SLEEP_DELAY)  //to increase time between ranging, modify POLL_SLEEP_DELAY
+//#define BLINK_FREQUENCY							0.0001
+#define BLINK_PERIOD_MS							1000     //time to wait between sending blink messages
+
+#define RX_CHECK_ON_PERIOD						200 //TODO modify
+
+// Reception start-up time, in symbols.
+#define RX_START_UP_SY 16
+
+//TDMA defines
+#define MIN_FRAMELENGTH							4 //minimum size by TDMA E-ASAP
+
+typedef uint64_t        uint64 ;
+
+typedef int64_t         int64 ;
+
+
+typedef enum instanceModes{DISCOVERY, CONNECTION_PENDING, TAG, ANCHOR, NUM_MODES} INST_MODE;
+
+typedef enum discovery_modes
+{
+	WAIT_INF_REG,
+	COLLECT_INF_REG,
+	WAIT_INF_INIT,
+	WAIT_RNG_INIT,
+	WAIT_SEND_SUG,
+	SEND_SUG,
+	EXIT
+}
+DISCOVERY_MODE;
+
+
+//Listener = in this mode, the instance only receives frames, does not respond
+//Tag = Exchanges DecaRanging messages (Poll-Response-Final) with Anchor and enabling Anchor to calculate the range between the two instances
+//Anchor = see above
+
+typedef enum inst_states
+{
+    TA_INIT,                    //0
+    TA_TXE_WAIT,                //1
+    TA_TXINF_WAIT_SEND,			//2
+    TA_TXPOLL_WAIT_SEND,        //3
+    TA_TXFINAL_WAIT_SEND,       //4
+    TA_TXRESPONSE_WAIT_SEND,    //5
+    TA_TX_WAIT_CONF,            //6
+    TA_RXE_WAIT,                //7
+    TA_RX_WAIT_DATA,            //8
+    TA_SLEEP_DONE,              //9
+    TA_TXBLINK_WAIT_SEND,       //10
+    TA_TXRANGINGINIT_WAIT_SEND, //11
+    TA_TX_SELECT,               //12
+    TA_MODE_SELECT,				//13
+    TA_TXREPORT_WAIT_SEND,		//14
+    TA_TXSUG_WAIT_SEND			//15
+} INST_STATES;
+
+
+// This file defines data and functions for access to Parameters in the Device
+//message structure for Poll, Response and Final message
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
+    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	//  13-20 using 64 bit addresses
+    uint8 messageData[MAX_USER_PAYLOAD_STRING_LL] ; //  21-124 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_msg_dlsl ;
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
+    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	//  07-08
+    uint8 messageData[MAX_USER_PAYLOAD_STRING_SS] ; //  09-124 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_msg_dsss ;
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
+    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	//  13-14
+    uint8 messageData[MAX_USER_PAYLOAD_STRING_LS] ; //  15-124 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_msg_dlss ;
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
+    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	//  07-14 using 64 bit addresses
+    uint8 messageData[MAX_USER_PAYLOAD_STRING_LS] ; //  15-124 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_msg_dssl ;
+
+///// extended message definitions
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
+    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	//  13-20 using 64 bit addresses
+    uint8 messageData[MAX_EXTENDED_USER_PAYLOAD_STRING_LL] ; //  21-1020 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  1021-1022  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_ext_msg_dlsl ;
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
+    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	//  07-08
+    uint8 messageData[MAX_EXTENDED_USER_PAYLOAD_STRING_SS] ; //  09-1020 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  1021-1022  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_ext_msg_dsss ;
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
+    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	//  13-14
+    uint8 messageData[MAX_EXTENDED_USER_PAYLOAD_STRING_LS] ; //  15-1020 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  1021-1022  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_ext_msg_dlss ;
+
+typedef struct
+{
+    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8 seqNum;                               	//  sequence_number 02
+    uint8 panID[2];                             	//  PAN ID 03-04
+    uint8 destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
+    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	//  07-14 using 64 bit addresses
+    uint8 messageData[MAX_EXTENDED_USER_PAYLOAD_STRING_LS] ; //  15-1020 (application data and any user payload)
+    uint8 fcs[2] ;                              	//  1021-1022  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} srd_ext_msg_dssl ;
+
+
+
+//12 octets for Minimum IEEE ID blink
+typedef struct
+{
+    uint8 frameCtrl;                         		//  frame control bytes 00
+    uint8 seqNum;                               	//  sequence_number 01
+    uint8 tagID[BLINK_FRAME_SOURCE_ADDRESS];        //  02-09 64 bit address
+    uint8 fcs[2] ;                              	//  10-11  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+} iso_IEEE_EUI64_blink_msg ;
+
+typedef struct
+{
+    uint8 channelNumber ;       // valid range is 1 to 11
+    uint8 preambleCode ;        // 00 = use NS code, 1 to 24 selects code
+    uint8 pulseRepFreq ;        // NOMINAL_4M, NOMINAL_16M, or NOMINAL_64M
+    uint8 dataRate ;            // DATA_RATE_1 (110K), DATA_RATE_2 (850K), DATA_RATE_3 (6M81)
+    uint8 preambleLen ;         // values expected are 64, (128), (256), (512), 1024, (2048), and 4096
+    uint8 pacSize ;
+    uint8 nsSFD ;
+    uint16 sfdTO;  //!< SFD timeout value (in symbols) e.g. preamble length (128) + SFD(8) - PAC + some margin ~ 135us... DWT_SFDTOC_DEF; //default value
+} instanceConfig_t ;
+
+
+/******************************************************************************************************************
+*******************************************************************************************************************
+*******************************************************************************************************************/
+
+#define MAX_EVENT_NUMBER (8)
+//NOTE: Accumulators don't need to be stored as part of the event structure as when reading them only one RX event can happen...
+//the receiver is singly buffered and will stop after a frame is received
+
+typedef struct
+{
+	uint8  type;			// event type
+	uint8  typeSave;		// holds the event type - does not clear (used to show what event has been processed)
+	uint8  typePend;	    // set if there is a pending event (i.e. DW is not in IDLE (TX/RX pending)
+	uint16 rxLength ;
+
+	uint64 timeStamp ;		// last timestamp (Tx or Rx)
+
+	uint32 timeStamp32l ;		   // last tx/rx timestamp - low 32 bits
+	uint32 timeStamp32h ;		   // last tx/rx timestamp - high 32 bits
+
+	union {
+			//holds received frame (after a good RX frame event)
+			uint8   frame[EXTENDED_FRAME_SIZE];
+			srd_ext_msg_dlsl rxmsg_ll ; //64 bit addresses
+			srd_ext_msg_dssl rxmsg_sl ;
+			srd_ext_msg_dlss rxmsg_ls ;
+			srd_ext_msg_dsss rxmsg_ss ; //16 bit addresses
+			iso_IEEE_EUI64_blink_msg rxblinkmsg;
+	}msgu;
+
+}event_data_t ;
+
+#define RTD_MED_SZ          8      // buffer size for mean of 8
+
+typedef struct {
+                uint8 PGdelay;
+
+                //TX POWER
+                //31:24     BOOST_0.125ms_PWR
+                //23:16     BOOST_0.25ms_PWR-TX_SHR_PWR
+                //15:8      BOOST_0.5ms_PWR-TX_PHR_PWR
+                //7:0       DEFAULT_PWR-TX_DATA_PWR
+                uint32 txPwr[2]; //
+}tx_struct;
+
+
+
+
+
+#endif
diff --git a/src/application/comm_scheduler.c b/src/application/comm_scheduler.c
index f70aa1c..36b207f 100644
--- a/src/application/comm_scheduler.c
+++ b/src/application/comm_scheduler.c
@@ -1,46 +1,46 @@
-#include "comm_scheduler.h"
-#include "port.h"
-
-//private mehtods
-//int node_compare(llist_node first, llist_node second)
-//{
-//    timing_node *first_node = (timing_node *)first;
-//    timing_node *second_node = (timing_node *)second;
+//#include "comm_scheduler.h"
+//#include "port.h"
 //
-//    if(first_node->time == second_node->time)
-//    {
-//        return 0;
-//    }
-//    else if(first_node->time > second_node->time)
-//    {
-//        return 1;
-//    }
-//    else
-//    {
-//        return -1;
-//    }
-//	return 0;
-//}
+////private mehtods
+////int node_compare(llist_node first, llist_node second)
+////{
+////    timing_node *first_node = (timing_node *)first;
+////    timing_node *second_node = (timing_node *)second;
+////
+////    if(first_node->time == second_node->time)
+////    {
+////        return 0;
+////    }
+////    else if(first_node->time > second_node->time)
+////    {
+////        return 1;
+////    }
+////    else
+////    {
+////        return -1;
+////    }
+////	return 0;
+////}
+////
+////
+////bool node_equal(llist_node first, llist_node second)
+////{
+////    if(first == second){return true;}
+////
+////    return false;
+////}
 //
 //
-//bool node_equal(llist_node first, llist_node second)
-//{
-//    if(first == second){return true;}
+////class methods
 //
-//    return false;
+//static struct CommScheduler new(float blink_frequency, uint32 blink_duration, uint32 range_duration){
+//    return (struct CommScheduler){
+////        .list = llist_create(node_compare, node_equal, 0),
+//		.blink_frequency = blink_frequency,
+//		.blink_duration = blink_duration,
+//		.range_duration = range_duration,
+//		.blink_period = (int)(1.0/blink_frequency)
+//    };
 //}
-
-
-//class methods
-
-static struct CommScheduler new(float blink_frequency, uint32 blink_duration, uint32 range_duration){
-    return (struct CommScheduler){
-//        .list = llist_create(node_compare, node_equal, 0),
-		.blink_frequency = blink_frequency,
-		.blink_duration = blink_duration,
-		.range_duration = range_duration,
-		.blink_period = (int)(1.0/blink_frequency)
-    };
-}
-
-const struct CommSchedulerClass CommScheduler={.new=&new};
+//
+//const struct CommSchedulerClass CommScheduler={.new=&new};
diff --git a/src/application/comm_scheduler.h b/src/application/comm_scheduler.h
index d7b9c3e..d2bc91d 100644
--- a/src/application/comm_scheduler.h
+++ b/src/application/comm_scheduler.h
@@ -1,25 +1,25 @@
-#include "llist.h"
-#include "deca_types.h"
-
-typedef struct
-{
-	uint32 time;      			//time the node is scheduled to be used.
-	uint32 duration;            //expected time the node event will take before completion
-
-} timing_node ;
-
-struct CommScheduler
-{
-    llist list;
-
-    uint32 blink_frequency;
-    uint32 blink_period;
-    uint32 blink_duration;
-    uint32 range_duration;
-};
-
-extern const struct CommSchedulerClass
-{
-	struct CommScheduler (*new)(float blink_frequency, uint32 blink_duration, uint32 range_duration);
-
-} CommScheduler;
+//#include "llist.h"
+//#include "deca_types.h"
+//
+//typedef struct
+//{
+//	uint32 time;      			//time the node is scheduled to be used.
+//	uint32 duration;            //expected time the node event will take before completion
+//
+//} timing_node ;
+//
+//struct CommScheduler
+//{
+//    llist list;
+//
+//    uint32 blink_frequency;
+//    uint32 blink_period;
+//    uint32 blink_duration;
+//    uint32 range_duration;
+//};
+//
+//extern const struct CommSchedulerClass
+//{
+//	struct CommScheduler (*new)(float blink_frequency, uint32 blink_duration, uint32 range_duration);
+//
+//} CommScheduler;
diff --git a/src/application/dw_main.c b/src/application/dw_main.c
index 9929873..336fdba 100644
--- a/src/application/dw_main.c
+++ b/src/application/dw_main.c
@@ -36,7 +36,7 @@ extern void send_usbmessage(uint8*, int);
 #define SWS1_CH5_MODE		0x40  //channel 5 mode (switch S1-7)
 
 int dr_mode = 0;
-int instance_mode = ANCHOR;
+int instance_mode = DISCOVERY;
 
 uint8 s1switch = 0;
 int chan, tagaddr, ancaddr, prf;
@@ -191,6 +191,8 @@ uint32 inittestapplication(uint8 s1switch)
     result = instance_init() ;
     if (0 > result) return(-1) ; // Some failure has occurred
 
+    result = tdma_init_s();
+
     port_set_dw1000_fastrate();
     devID = instancereaddeviceid() ;
 
@@ -202,19 +204,19 @@ uint32 inittestapplication(uint8 s1switch)
 
     if(s1switch & SWS1_ANC_MODE)
     {
-        instance_mode = ANCHOR;
+//        instance_mode = ANCHOR;
 
         led_on(LED_PC6);
 
     }
     else
     {
-        instance_mode = TAG;
+//        instance_mode = TAG;
         led_on(LED_PC7);
     }
 
-    instance_init_s(instance_mode);
-    dr_mode = decarangingmode(s1switch);
+    instance_init_s();
+	dr_mode = decarangingmode(s1switch);
 
     chan = chConfig[dr_mode].channelNumber ;
     prf = (chConfig[dr_mode].pulseRepFreq == DWT_PRF_16M)? 16 : 64 ;
@@ -329,6 +331,8 @@ int dw_main(void)
     // enable the USB functionality
     usb_init();
     Sleep(1000);
+    usb_run();
+    Sleep(10000);
 #endif
 
     s1switch = port_is_boot1_on(0) << 1 // is_switch_on(TA_SW1_2) << 2
@@ -449,32 +453,32 @@ int dw_main(void)
 #endif
         if(s1switch & SWS1_ANC_MODE)
         {
-            instance_mode = ANCHOR;
+//            instance_mode = ANCHOR;
 
             led_on(LED_PC6);
         }
         else
         {
-            instance_mode = TAG;
+//            instance_mode = TAG;
             led_on(LED_PC7);
         }
 
 #if (USING_LCD == 1)
-        if(instance_mode == TAG)
-        {
-			memcpy(&dataseq[0], (const uint8 *) "   TAG BLINK    ", 16);
+//        if(instance_mode == TAG)
+//        {
+			memcpy(&dataseq[0], (const uint8 *) " DISCOVERY MODE ", 16);
 
 			writetoLCD( 40, 1, dataseq); //send some data
 			sprintf((char*)&dataseq[0], "%llX", instance_get_addr());
 			writetoLCD( 16, 1, dataseq); //send some data
-        }
-        else
-        {
-            memcpy(&dataseq[0], (const uint8 *) "    AWAITING    ", 16);
-            writetoLCD( 40, 1, dataseq); //send some data
-            memcpy(&dataseq[0], (const uint8 *) "      POLL      ", 16);
-            writetoLCD( 16, 1, dataseq); //send some data
-        }
+//        }
+//        else
+//        {
+//            memcpy(&dataseq[0], (const uint8 *) "    AWAITING    ", 16);
+//            writetoLCD( 40, 1, dataseq); //send some data
+//            memcpy(&dataseq[0], (const uint8 *) "      POLL      ", 16);
+//            writetoLCD( 16, 1, dataseq); //send some data
+//        }
 
         command = 0x2 ;  //return cursor home
         writetoLCD( 1, 0,  &command);
@@ -494,12 +498,13 @@ int dw_main(void)
         
 		instance_data_t* inst = instance_get_local_structure_ptr(0);
 		canSleep = instance_run(); //run the state machine!!!
+		instance_mode = inst->mode; //TODO modify how the rest of this works with DISCOVER, TAG, and ANCHOR!
 
         if(instancenewrange())
         {
         	int n, rng, rng_raw;
             uint64 aaddr, taddr;
-            ranging = 1;
+//            ranging = 1;
             //send the new range information to LCD and/or USB
             range_result = instance_get_idist(inst->newRangeUWBIndex);
 //            uint8 debug_msg[200];
@@ -570,28 +575,43 @@ int dw_main(void)
             rng = (int) (range_result*1000);
             rng_raw = (int) (instance_get_idistraw(inst->newRangeUWBIndex)*1000);
 
-            if(instance_mode == TAG)
-            {
-                n = sprintf((char*)&dataseq[0], "t %llX %llX %08X %08X", aaddr, taddr, rng, rng_raw);
-                          
-            }
-            else
-            {
-//                n = sprintf((char*)&dataseq[0], "a %llX %llX %08X %08X", aaddr, taddr, rng, rng_raw);
-                n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr);
-            }
+
+
+//            n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr);
+//            n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr);
+
+			if(instance_mode == TAG)
+			{
+//				n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr);
+
+			}
+			else
+			{
+//				n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr);
+			}
+
+//            if(instance_mode == TAG)
+//            {
+//                n = sprintf((char*)&dataseq[0], "t %llX %llX %08X %08X", aaddr, taddr, rng, rng_raw);
+//
+//            }
+//            else
+//            {
+////                n = sprintf((char*)&dataseq[0], "a %llX %llX %08X %08X", aaddr, taddr, rng, rng_raw);
+//                n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr);
+//            }
 
 #ifdef USB_SUPPORT //this is set in the port.h file
-           if(instance_mode == ANCHOR)
+           if(instance_mode == TAG)
            {
-        	   send_usbmessage(&dataseq[0], n);
+//        	   send_usbmessage(&dataseq[0], n);
            }
 //           send_usbmessage(&dataseq[0], n);
 #endif
         }
 
 #if (USING_LCD == 1)
-        if(ranging == 0) //discovery/initialization mode for anchor and tag
+        if(instanceisranging() == 0) //discovery/initialization mode for anchor and tag
         {
             if(instance_mode != ANCHOR)
             {
@@ -620,7 +640,7 @@ int dw_main(void)
 
                 if(instanceanchorwaiting() == 2)
                 {
-                    ranging = 1;
+//                    ranging = 1;
                     dataseq[0] = 0x2 ;  //return cursor home
                     writetoLCD( 1, 0,  dataseq);
                     memcpy(&dataseq[0], (const uint8 *) "    RANGING     ", 16);
@@ -676,7 +696,7 @@ int dw_main(void)
 #endif
 
 #ifdef USB_SUPPORT //this is set in the port.h file
-        usb_run();
+//        usb_run();
 #endif
 
         if(canSleep)__WFI();
diff --git a/src/application/instance.c b/src/application/instance.c
index 0c1c67c..18529f7 100644
--- a/src/application/instance.c
+++ b/src/application/instance.c
@@ -20,7 +20,7 @@
 #include "lib.h"
 #include "instance.h"
 
-#include "llist.h"
+//#include "llist.h"
 
 
 
@@ -59,6 +59,8 @@ int usbtxdebugdataprev_size = 0;
 // Functions
 // -------------------------------------------------------------------------------------------------------------------
 
+
+
 // -------------------------------------------------------------------------------------------------------------------
 //
 // function to construct the message/frame header bytes
@@ -67,24 +69,166 @@ int usbtxdebugdataprev_size = 0;
 //
 void instanceconfigframeheader(instance_data_t *inst)
 {
-    inst->msg[inst->uwbToRangeWith].panID[0] = (inst->panID) & 0xff;
-    inst->msg[inst->uwbToRangeWith].panID[1] = inst->panID >> 8;
 
-    //set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
-    inst->msg[inst->uwbToRangeWith].frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
+//	//configure ranging message(s)
+//	for(int i = 0; i < UWB_LIST_SIZE; i++)//TODO only have one msg
+//	{
+//		inst->msg[i].panID[0] = (inst->panID) & 0xff;
+//		inst->msg[i].panID[1] = inst->panID >> 8;
+//
+//		//set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
+//		inst->msg[i].frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
+//#if (USING_64BIT_ADDR==1)
+//		    //source/dest addressing modes and frame version
+//		inst->msg[i].frameCtrl[1] = 0xC /*dest extended address (64bits)*/ | 0xC0 /*src extended address (64bits)*/;
+//#else
+//		inst->msg[i].frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0x80 /*src short address (16bits)*/;
+//#endif
+//	}
+
+	//configure ranging message
+	inst->msg.panID[0] = (inst->panID) & 0xff;
+	inst->msg.panID[1] = inst->panID >> 8;
+
+	//set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
+	inst->msg.frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
+#if (USING_64BIT_ADDR==1)
+		//source/dest addressing modes and frame version
+	inst->msg.frameCtrl[1] = 0xC /*dest extended address (64bits)*/ | 0xC0 /*src extended address (64bits)*/;
+#else
+	inst->msg.frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0x80 /*src short address (16bits)*/;
+#endif
+
+
+	//configure RNG_INIT message
+    inst->rng_initmsg.frameCtrl[0] = 0x41;
+
+#if (USING_64BIT_ADDR == 1)
+    inst->rng_initmsg.frameCtrl[1] = 0xCC;
+#else
+    inst->rng_initmsg.frameCtrl[1] = 0x8C;
+#endif
+    inst->rng_initmsg.panID[0] = (inst->panID) & 0xff;
+    inst->rng_initmsg.panID[1] = inst->panID >> 8;
+
+
+	//configure INF message
+	inst->inf_msg.panID[0] = (inst->panID) & 0xff;
+	inst->inf_msg.panID[1] = inst->panID >> 8;
+
+	//set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
+	inst->inf_msg.frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
 #if (USING_64BIT_ADDR==1)
-    //source/dest addressing modes and frame version
-    inst->msg[inst->uwbToRangeWith].frameCtrl[1] = 0xC /*dest extended address (64bits)*/ | 0xC0 /*src extended address (64bits)*/;
+	//source/dest addressing modes and frame version
+	inst->inf_msg.frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0xC0 /*src extended address (64bits)*/;
 #else
-    inst->msg[inst->uwbToRangeWith].frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0x80 /*src short address (16bits)*/;
+	inst->inf_msg.frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0x80 /*src short address (16bits)*/;
 #endif
+
+
+	//configure RNG_REPORT
+
+	inst->report_msg.panID[0] = (inst->panID) & 0xff;
+	inst->report_msg.panID[1] = inst->panID >> 8;
+
+	//set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
+	inst->report_msg.frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
+#if (USING_64BIT_ADDR==1)
+	//source/dest addressing modes and frame version
+	inst->report_msg.frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0xC0 /*src extended address (64bits)*/;
+#else
+	inst->report_msg.frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0x80 /*src short address (16bits)*/;
+#endif
+
+
+	//configure BLINK
+	//blink frames with IEEE EUI-64 tag ID
+	inst->blinkmsg.frameCtrl = 0xC5 ;
+
+
+
+
+////////////////////// OLD definition below	//////////////////////
+//    inst->msg[inst->uwbToRangeWith].panID[0] = (inst->panID) & 0xff;
+//    inst->msg[inst->uwbToRangeWith].panID[1] = inst->panID >> 8;
+//
+//    //set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
+//    inst->msg[inst->uwbToRangeWith].frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
+//#if (USING_64BIT_ADDR==1)
+//    //source/dest addressing modes and frame version
+//    inst->msg[inst->uwbToRangeWith].frameCtrl[1] = 0xC /*dest extended address (64bits)*/ | 0xC0 /*src extended address (64bits)*/;
+//#else
+//    inst->msg[inst->uwbToRangeWith].frameCtrl[1] = 0x8 /*dest short address (16bits)*/ | 0x80 /*src short address (16bits)*/;
+//#endif
+}
+
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// function to construct the fixed portions of the message definitions
+//
+// -------------------------------------------------------------------------------------------------------------------
+//
+void instanceconfigmessages(instance_data_t *inst)
+{
+	//initialize ranging message(s)
+	//set source address into the message structure
+//	for(int i=0; i<UWB_LIST_SIZE; i++) //TODO only have 1 msg? or one Tag msg, one Anchor msg?
+//	{
+//		memcpy(&inst->msg[i].sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
+//	}
+
+	memcpy(&inst->msg.sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
+
+
+	//initialize RNG_INIT message
+	//set source address into the message structure
+	memcpy(&inst->rng_initmsg.sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
+	inst->rng_initmsg.messageData[FCODE] = RTLS_DEMO_MSG_RNG_INIT;
+
+	//these bytes not used, zero them out.
+	inst->rng_initmsg.messageData[RNG_INIT_TAG_SHORT_ADDR_LO] = 0x00;
+	inst->rng_initmsg.messageData[RNG_INIT_TAG_SHORT_ADDR_HI] = 0x00;
+
+	uint16 resp_dly_us, resp_dly;
+	// First response delay to send is anchor's response delay.
+	resp_dly_us = ANC_TURN_AROUND_TIME_US + inst->frameLengths_us[POLL];
+	resp_dly = ((RESP_DLY_UNIT_US << RESP_DLY_UNIT_SHIFT) & RESP_DLY_UNIT_MASK)
+				+ ((resp_dly_us << RESP_DLY_VAL_SHIFT) & RESP_DLY_VAL_MASK);
+	inst->rng_initmsg.messageData[RNG_INIT_ANC_RESP_DLY_LO] = resp_dly & 0xFF;
+	inst->rng_initmsg.messageData[RNG_INIT_ANC_RESP_DLY_HI] = (resp_dly >> 8) & 0xFF;
+	// Second response delay to send is tag's response delay.
+	resp_dly_us = TAG_TURN_AROUND_TIME_US + inst->frameLengths_us[RESP];
+	resp_dly = ((RESP_DLY_UNIT_US << RESP_DLY_UNIT_SHIFT) & RESP_DLY_UNIT_MASK)
+				+ ((resp_dly_us << RESP_DLY_VAL_SHIFT) & RESP_DLY_VAL_MASK);
+	inst->rng_initmsg.messageData[RNG_INIT_TAG_RESP_DLY_LO] = resp_dly & 0xFF;
+	inst->rng_initmsg.messageData[RNG_INIT_TAG_RESP_DLY_HI] = (resp_dly >> 8) & 0xFF;
+
+	//configure INF message
+	uint16 broadcast_address = BROADCAST_ADDRESS;
+	memcpy(&inst->inf_msg.sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
+	memcpy(&inst->inf_msg.destAddr[0], &broadcast_address, 2);
+	inst->inf_msg.messageData[FCODE] = 0; //message function code (specifies if message is a poll, response or other...)
+
+	//configure RNG_REPORT
+	memcpy(&inst->report_msg.sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
+	memcpy(&inst->report_msg.destAddr[0], &broadcast_address, 2);
+	inst->report_msg.messageData[FCODE] = RTLS_DEMO_MSG_RNG_REPORT; //message function code (specifies if message is a poll, response or other...)
+
+
+	//configure BLINK message
+	memcpy(&inst->blinkmsg.tagID[0], &inst->eui64[0], ADDR_BYTE_SIZE_L);
+
 }
 
 
+
 // -------------------------------------------------------------------------------------------------------------------
 //
 // Turn on the receiver with/without delay
 //
+// -------------------------------------------------------------------------------------------------------------------
+//
 void instancerxon(instance_data_t *inst, int delayed, uint64 delayedReceiveTime)
 {
     if (delayed)
@@ -96,12 +240,12 @@ void instancerxon(instance_data_t *inst, int delayed, uint64 delayedReceiveTime)
 
 //    inst->lateRX -= dwt_rxenable(delayed) ;  //- as when fails -1 is returned             // turn receiver on, immediate/delayed
 
-    uint32 time_now = portGetTickCnt();
+//    uint32 time_now = portGetTickCnt();
     int dwt_rx_enable_return = dwt_rxenable(delayed);
-	 uint8 debug_msg[100];
-	 int n = sprintf((char*)&debug_msg[0], "RX_ENABLE time_now: %lu, rx_enable: %i", time_now, dwt_rx_enable_return);
-	 send_usbmessage(&debug_msg[0], n);
-	 usb_run();
+//	 uint8 debug_msg[100];
+//	 int n = sprintf((char*)&debug_msg[0], "RX_ENABLE time_now: %lu, rx_enable: %i", time_now, dwt_rx_enable_return);
+//	 send_usbmessage(&debug_msg[0], n);
+//	 usb_run();
 	 inst->lateRX -= dwt_rx_enable_return;
 
 } // end instancerxon()
@@ -141,9 +285,13 @@ const char* get_inst_states_string(enum inst_states state)
         case TA_RXE_WAIT : return "TA_RXE_WAIT";
         case TA_RX_WAIT_DATA : return "TA_RX_WAIT_DATA";
         case TA_SLEEP_DONE : return "TA_SLEEP_DONE";
+        case TA_TXINF_WAIT_SEND : return "TA_TXINF_WAIT_SEND";
         case TA_TXBLINK_WAIT_SEND : return "TA_TXBLINK_WAIT_SEND";
         case TA_TXRANGINGINIT_WAIT_SEND : return "TA_TXRANGINGINIT_WAIT_SEND";
         case TA_TX_SELECT : return "TA_TX_SELECT";
+        case TA_MODE_SELECT : return "TA_MODE_SELECT";
+        case TA_TXREPORT_WAIT_SEND : return "TA_TXREPORT_WAIT_SEND";
+        case TA_TXSUG_WAIT_SEND : return "TA_TXSUG_WAIT_SEND";
         default: return "NONE";
     }
 }
@@ -153,15 +301,32 @@ const char* get_instanceModes_string(enum instanceModes mode)
 {
     switch (mode)
     {
-        case LISTENER : return "LISTENER";
+    	case DISCOVERY : return "DISCOVERY";
+    	case CONNECTION_PENDING : return "CONNECTION_PENDING";
         case TAG : return "TAG";       
-        case ANCHOR : return "ANCHOR";       
-        case TAG_TDOA : return "TAG_TDOA";  
+        case ANCHOR : return "ANCHOR";
         case NUM_MODES : return "NUM_MODES";
         default: return "NONE";
     }
 }
 
+//debug helper function to print the mode
+const char* get_discovery_modes_string(enum discovery_modes mode)
+{
+    switch (mode)
+    {
+    	case WAIT_INF_REG : return "WAIT_INF_REG";
+    	case COLLECT_INF_REG : return "COLLECT_INF_REG";
+        case WAIT_INF_INIT : return "WAIT_INF_INIT";
+        case WAIT_RNG_INIT : return "WAIT_RNG_INIT";
+        case WAIT_SEND_SUG : return "WAIT_SEND_SUG";
+        case SEND_SUG : return "SEND_SUG";
+        case EXIT : return "EXIT";
+        default: return "NONE";
+    }
+}
+
+
 char* get_msg_fcode_string(int fcode)
 {
     if (fcode == (int)RTLS_DEMO_MSG_RNG_INIT)
@@ -180,13 +345,34 @@ char* get_msg_fcode_string(int fcode)
     {
         return "RTLS_DEMO_MSG_TAG_FINAL";
     }
+    else if(fcode == (int)RTLS_DEMO_MSG_INF_REG)
+    {
+    	return "RTLS_DEMO_MSG_INF_REG";
+    }
+    else if(fcode == (int)RTLS_DEMO_MSG_INF_INIT)
+	{
+		return "RTLS_DEMO_MSG_INF_INIT";
+	}
+    else if(fcode == (int)RTLS_DEMO_MSG_INF_SUG)
+	{
+		return "RTLS_DEMO_MSG_INF_SUG";
+	}
+	else if(fcode == (int)RTLS_DEMO_MSG_INF_UPDATE)
+	{
+		return "RTLS_DEMO_MSG_INF_UPDATE";
+	}
+    else if(fcode == (int)RTLS_DEMO_MSG_RNG_REPORT)
+	{
+		return "RTLS_DEMO_MSG_RNG_REPORT";
+	}
     else
     {
         return "NONE";
     }
 }
 
-void send_statetousb(instance_data_t *inst)
+//void send_statetousb(instance_data_t *inst)
+void send_statetousb(instance_data_t *inst, struct TDMAHandler *tdma_handler)
 {
     
     int usbdebugdata_size = sprintf((char*)&usbdebugdata[0], "%s , %s , %s , %s", get_inst_states_string(inst->testAppState), get_inst_states_string(inst->previousState), get_inst_states_string(inst->nextState), get_instanceModes_string(inst->mode));
@@ -197,6 +383,13 @@ void send_statetousb(instance_data_t *inst)
         usb_run();
         usbdebugdataprev_size = usbdebugdata_size;
         memcpy(usbdebugdataprev, usbdebugdata, usbdebugdata_size);
+
+        int num_neighbors = instfindnumactiveneighbors(inst);
+		uint8 debug_msg[150];
+		int n = sprintf((char*)&debug_msg[0], "mode: %s, num_neighbors %d, discovery_mode %s", get_instanceModes_string(inst->mode), num_neighbors, get_discovery_modes_string(tdma_handler->discovery_mode));
+		send_usbmessage(&debug_msg[0], n);
+		usb_run();
+
     }
 }
 
@@ -223,66 +416,64 @@ void send_txmsgtousb(char *data)
 
 // -------------------------------------------------------------------------------------------------------------------
 //
-// the main instance state machine (all the instance modes Tag, Anchor or Listener use the same statemachine....)
+// the main instance state machine (all the instance modes Tag or Anchor use the same state machine)
 //
 // -------------------------------------------------------------------------------------------------------------------
 //
-int testapprun(instance_data_t *inst, int message)
+int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int message)
 {
     int done = INST_NOT_DONE_YET;
-    
+
 //    uint8 debug_msg[100];
 //	int n = sprintf((char *)&debug_msg, "TAR");
 //	send_usbmessage(&debug_msg[0], n);
 //	usb_run();
 
 
+//    tdma_handler->set_slot(tdma_handler);
+    if(tdma_handler->slot_transition(tdma_handler))
+    {
+		message = 0;
+    }
+
+    tdma_handler->check_discovery_mode_expiration(tdma_handler);
+
     //NOTE: temporary debug code
     if(inst->testAppState != inst->lastState){
     	inst->currentStateStartTime = portGetTickCnt();
     }
     inst->lastState = inst->testAppState;
 
-    send_statetousb(inst);
-
+    send_statetousb(inst, tdma_handler);
 
 
     switch (inst->testAppState)
     {
         case TA_INIT :
         {
-            // if (inst->mode == ANCHOR)
-            // {
-            //     send_statetousb(inst);
-            // }
 
             switch (inst->mode)
             {
-                case TAG:
+                case DISCOVERY:
                 {
                     int mode = 0;
+                    dwt_forcetrxoff();
 
-                    dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN); //allow data, ACK frames;
-                    inst->frameFilteringEnabled = 1 ;
-                    dwt_setpanid(inst->panID);
-                    dwt_seteui(inst->eui64);
+                    dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN | DWT_FF_RSVD_EN);
+					inst->frameFilteringEnabled = 1 ;
+					dwt_seteui(inst->eui64);
+					dwt_setpanid(inst->panID);
+
+					inst->uwbShortAdd = inst->eui64[0] + (inst->eui64[1] << 8);//TODO use a hashing algorithm
 
-                    inst->uwbShortAdd = inst->eui64[0] + (inst->eui64[1] << 8);
-                    
-                    
 #if (USING_64BIT_ADDR==0)
-                    dwt_setaddress16(inst->uwbShortAdd);
+					dwt_setaddress16(inst->uwbShortAdd);
+					memcpy(&inst->uwbList[0][0], &inst->uwbShortAdd, inst->addrByteSize);
+#else
+					memcpy(&inst->uwbList[0][0], &inst->eui64, inst->addrByteSize);
 #endif
-
-                    //set source address into the message structure
-                    for(int i=0; i<UWB_LIST_SIZE; i++)
-                    {
-                        memcpy(&inst->msg[i].sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
-                    }
-
-                    inst->testAppState = TA_TXBLINK_WAIT_SEND;
-                    inst->tx_scheduler.last_blink_time = portGetTickCnt();
-                    memcpy(&inst->blinkmsg.tagID[0], &inst->eui64[0], ADDR_BYTE_SIZE_L);
+					inst->uwbListLen = 1;
+					inst->uwbListType[0] = UWB_LIST_SELF;
 
                     mode = (DWT_PRESRV_SLEEP|DWT_CONFIG|DWT_TANDV);
 
@@ -295,77 +486,49 @@ int testapprun(instance_data_t *inst, int message)
                         dwt_configuresleep(mode, DWT_WAKE_WK|DWT_WAKE_CS|DWT_SLP_EN); //configure the on wake parameters (upload the IC config settings)
 #endif
 
-                }
-                break;
-                case ANCHOR:
-                {
-                    dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN | DWT_FF_RSVD_EN);
-                    inst->frameFilteringEnabled = 1 ;
-                    dwt_seteui(inst->eui64);
-                    dwt_setpanid(inst->panID);
-
-                    inst->uwbShortAdd = inst->eui64[0] + (inst->eui64[1] << 8);
-
-#if (USING_64BIT_ADDR==0)
-                    dwt_setaddress16(inst->uwbShortAdd);
-#endif
+                    instanceconfigframeheader(inst);
+                    instanceconfigmessages(inst);
 
-                    //set source address into the message structure
-                    for(int i=0; i<UWB_LIST_SIZE; i++)
-                    {
-                        memcpy(&inst->msg[i].sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
-                    }
-                    //set source address into the message structure
-                    memcpy(&inst->rng_initmsg.sourceAddr[0], &inst->eui64[0], inst->addrByteSize);
+                    // First time listening we don't do a delayed RX
+					 dwt_setrxaftertxdelay(0);
+					//change to next state - wait to receive a message
+					tdma_handler->discoveryStartTime = portGetTickCnt();
+					tdma_handler->last_blink_time = portGetTickCnt();
+					inst->testAppState = TA_RXE_WAIT ;
 
-                    // First time anchor listens we don't do a delayed RX
-                    dwt_setrxaftertxdelay(0);
-                    //change to next state - wait to receive a message
-                    inst->testAppState = TA_RXE_WAIT ;
+					dwt_setrxtimeout(0);
+					inst->canPrintInfo = 1;
+					inst->wait4ack = 0;
 
-                    dwt_setrxtimeout(0);
-                    inst->canPrintInfo = 1;
                 }
                 break;
-                case LISTENER:
-                {
-                    dwt_enableframefilter(DWT_FF_NOTYPE_EN); //disable frame filtering
-                    inst->frameFilteringEnabled = 0 ;
-                    // First time anchor listens we don't do a delayed RX
-                    dwt_setrxaftertxdelay(0);
-                    //change to next state - wait to receive a message
-                    inst->testAppState = TA_RXE_WAIT ;
-
-                    dwt_setrxtimeout(0);
-                }
-                break ; // end case TA_INIT
                 default:
                 break;
             }
             break; // end case TA_INIT
         }
-        case TA_TX_SELECT:
+        case TA_MODE_SELECT :
+        {
+        	//TODO maybe this will be used to transition between DISCOVERY/ANCHOR/TAG modes?
+        	break;
+        }
+        case TA_TX_SELECT :
         {
 //        	send_statetousb(inst);
             // select whether to blink or send out a range poll message.
             // select a uwb from the list if sending out a range poll message
-        	int uwb_index = inst->tx_scheduler.tx_select(&inst->tx_scheduler);
+//        	int uwb_index = inst->tx_scheduler.tx_select(&inst->tx_scheduler);
+
 
-//        	uint8 debug_msg[100];
-//			int n = sprintf((char *)&debug_msg, "selected index %i ", uwb_index);
-//			send_usbmessage(&debug_msg[0], n);
-//			usb_run();
 
-        	if(uwb_index < 0){
-        		//do nothing
-        		//TODO would be best to sleep until next possible poll and then select again...
-        		done = INST_DONE_WAIT_FOR_NEXT_EVENT; //TODO make sure that this is the right thing to do.
-        	}else if(uwb_index > 244){
-        		inst->testAppState = TA_TXBLINK_WAIT_SEND;
-        		inst->uwbToRangeWith = (uint8)255;
-        	}else{
-        		inst->testAppState = TA_TXPOLL_WAIT_SEND;
-        		inst->uwbToRangeWith = (uint8)uwb_index;
+          	//select a TX action, return if TRUE if we should move on to another state
+        	if(tdma_handler->tx_select(tdma_handler) == TRUE)
+        	{
+        		dwt_forcetrxoff();
+        	}
+        	else
+        	{
+        		done = INST_DONE_WAIT_FOR_NEXT_EVENT;
         	}
 
             break; // end case TA_TX_SELECT
@@ -377,7 +540,7 @@ int testapprun(instance_data_t *inst, int message)
 //                 send_statetousb(inst);
             // }
             event_data_t* dw_event = instance_getevent(10); //clear the event from the queue
-            // waiting for timout from application to wakup IC
+            // waiting for timeout from application to wakeup IC
             if (dw_event->type != DWT_SIG_RX_TIMEOUT)
             {
                 // if no pause and no wake-up timeout continue waiting for the sleep to be done.
@@ -406,13 +569,16 @@ int testapprun(instance_data_t *inst, int message)
                 //MP bug - TX antenna delay needs reprogramming as it is not preserved after DEEP SLEEP
                 dwt_settxantennadelay(inst->txAntennaDelay) ;
             }
+            instancesetantennadelays();
 #endif
-            instancesetantennadelays(); //this will update the antenna delay if it has changed
+            //TODO should this be here? or only if DEEP_SLEEP is enabled (above) putting only above for now
+//            instancesetantennadelays(); //this will update the antenna delay if it has changed
 
             break;
         }
         case TA_TXE_WAIT : //either go to sleep or proceed to TX a message
         {
+
             // if (inst->mode == ANCHOR)
             // {
             //     send_statetousb(inst);
@@ -429,7 +595,7 @@ int testapprun(instance_data_t *inst, int message)
                 done = INST_DONE_WAIT_FOR_NEXT_EVENT_TO; //don't sleep here but kick off the TagTimeoutTimer (instancetimer)
                 inst->testAppState = TA_SLEEP_DONE;
 
-                inst->canPrintInfo = 1;
+//                inst->canPrintInfo = 1;
 
 #if (DEEP_SLEEP == 1)
                 if (inst->sleepingEabled)
@@ -439,16 +605,16 @@ int testapprun(instance_data_t *inst, int message)
                 }
 #endif
                 //DW1000 gone to sleep - report the received range
-                if(inst->newRangeUWBIndex != 255)
-                {
-                    if(inst->tof[inst->newRangeUWBIndex] > 0) //if ToF == 0 - then no new range to report
-                    {
-                        if(reportTOF(inst, inst->newRangeUWBIndex)==0)
-                        {
-                            inst->newRange = 1;
-                        }
-                    }
-                }
+//                if(inst->newRangeUWBIndex != 255)
+//                {
+//                    if(inst->tof[inst->newRangeUWBIndex] > 0) //if ToF == 0 - then no new range to report
+//                    {
+//                        if(reportTOF(inst, inst->newRangeUWBIndex)==0)
+//                        {
+//                            inst->newRange = 1;
+//                        }
+//                    }
+//                }
                 
                 //inst->deviceissleeping = 1; //this is to stop polling device status register (as it will wake it up)
             }
@@ -468,8 +634,8 @@ int testapprun(instance_data_t *inst, int message)
                 
                 int flength = (BLINK_FRAME_CRTL_AND_ADDRESS + FRAME_CRC);
 
-                //blink frames with IEEE EUI-64 tag ID
-                inst->blinkmsg.frameCtrl = 0xC5 ;
+//                //blink frames with IEEE EUI-64 tag ID
+//                inst->blinkmsg.frameCtrl = 0xC5 ;
                 inst->blinkmsg.seqNum = inst->frameSN++;
 
                 dwt_writetxdata(flength, (uint8 *)  (&inst->blinkmsg), 0) ; // write the frame data
@@ -478,11 +644,12 @@ int testapprun(instance_data_t *inst, int message)
                 //using wait for response to do delayed receive
                 inst->wait4ack = DWT_RESPONSE_EXPECTED;
 
-                dwt_setrxtimeout((uint16)inst->fwtoTimeB_sy);  //units are symbols
+                //TODO fix!!! remove *0
+                dwt_setrxtimeout((uint16)inst->fwtoTimeB_sy*0);  //units are symbols
                 //set the delayed rx on time (the ranging init will be sent after this delay)
-                dwt_setrxaftertxdelay((uint32)inst->rnginitW4Rdelay_sy);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
+                dwt_setrxaftertxdelay((uint32)inst->rnginitW4Rdelay_sy*0);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
 
-                int tx_start = dwt_starttx(DWT_START_TX_IMMEDIATE | inst->wait4ack); //always using immediate TX and enable dealyed RX
+                int tx_start = dwt_starttx(DWT_START_TX_IMMEDIATE | inst->wait4ack); //always using immediate TX and enable delayed RX
                 
                 if(tx_start == 0)
                 {
@@ -506,8 +673,10 @@ int testapprun(instance_data_t *inst, int message)
 
 					inst->blink0range1 = 0;
                     inst->blink_start = portGetTickCnt();
-                    // send_txmsgtousb("BLINK-SUCCESS");
+//                     send_txmsgtousb("BLINK-SUCCESS");
                     inst->timeofTx = portGetTickCnt();
+                    tdma_handler->last_blink_time = portGetTickCnt();
+
                 }
                 else
                 {
@@ -531,39 +700,13 @@ int testapprun(instance_data_t *inst, int message)
             // }
 //            send_txmsgtousb("RTLS_DEMO_MSG_RNG_INIT");
 
-            uint16 resp_dly_us, resp_dly;
-
             int psduLength = RANGINGINIT_MSG_LEN;
 
-            inst->rng_initmsg.messageData[FCODE] = RTLS_DEMO_MSG_RNG_INIT;
-            //these bytes not used, zero them out.
-            inst->rng_initmsg.messageData[RNG_INIT_TAG_SHORT_ADDR_LO] = 0x00;
-            inst->rng_initmsg.messageData[RNG_INIT_TAG_SHORT_ADDR_HI] = 0x00;
-
-            // First response delay to send is anchor's response delay.
-            resp_dly_us = ANC_TURN_AROUND_TIME_US + inst->frameLengths_us[POLL];
-            resp_dly = ((RESP_DLY_UNIT_US << RESP_DLY_UNIT_SHIFT) & RESP_DLY_UNIT_MASK)
-                        + ((resp_dly_us << RESP_DLY_VAL_SHIFT) & RESP_DLY_VAL_MASK);
-            inst->rng_initmsg.messageData[RNG_INIT_ANC_RESP_DLY_LO] = resp_dly & 0xFF;
-            inst->rng_initmsg.messageData[RNG_INIT_ANC_RESP_DLY_HI] = (resp_dly >> 8) & 0xFF;
-            // Second response delay to send is tag's response delay.
-            resp_dly_us = TAG_TURN_AROUND_TIME_US + inst->frameLengths_us[RESP];
-            resp_dly = ((RESP_DLY_UNIT_US << RESP_DLY_UNIT_SHIFT) & RESP_DLY_UNIT_MASK)
-                        + ((resp_dly_us << RESP_DLY_VAL_SHIFT) & RESP_DLY_VAL_MASK);
-            inst->rng_initmsg.messageData[RNG_INIT_TAG_RESP_DLY_LO] = resp_dly & 0xFF;
-            inst->rng_initmsg.messageData[RNG_INIT_TAG_RESP_DLY_HI] = (resp_dly >> 8) & 0xFF;
-
-            inst->rng_initmsg.frameCtrl[0] = 0x41;
-
 #if (USING_64BIT_ADDR == 1)
-            inst->rng_initmsg.frameCtrl[1] = 0xCC;
             psduLength += FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;
 #else
-            inst->rng_initmsg.frameCtrl[1] = 0x8C;
             psduLength += FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC;
 #endif
-            inst->rng_initmsg.panID[0] = (inst->panID) & 0xff;
-            inst->rng_initmsg.panID[1] = inst->panID >> 8;
 
             inst->rng_initmsg.seqNum = inst->frameSN++;
 
@@ -581,52 +724,225 @@ int testapprun(instance_data_t *inst, int message)
                 inst->testAppState = TA_RXE_WAIT ;  // wait to receive a new blink or poll message
                 inst->wait4ack = 0; //clear the flag as the TX has failed the TRX is off
                 inst->lateTX++;
+                uint8 debug_msg[100];
+				sprintf((char *)&debug_msg, "RTLS_DEMO_MSG_RNG_INIT -> late tx");
+				send_txmsgtousb((char *)&debug_msg);
+				usb_run();
             }
             else
             {
+
                 inst->testAppState = TA_TX_WAIT_CONF ;                                               // wait confirmation
                 inst->previousState = TA_TXRANGINGINIT_WAIT_SEND ;
                 done = INST_DONE_WAIT_FOR_NEXT_EVENT;  //no timeout
 
-                //CONFIGURE FIXED PARTS OF RESPONSE MESSAGE FRAME (these won't change)
-                //program option octet and parameters (not used currently)
-                inst->msg[inst->uwbToRangeWith].messageData[RES_R1] = 0x2; // "activity"
-                inst->msg[inst->uwbToRangeWith].messageData[RES_R2] = 0x0; //
-                inst->msg[inst->uwbToRangeWith].messageData[RES_R3] = 0x0;
-                inst->msg[inst->uwbToRangeWith].messageData[FCODE] = RTLS_DEMO_MSG_ANCH_RESP; //message function code (specifies if message is a poll, response or other...)
-
-                instanceconfigframeheader(inst);
-                inst->timeofTx = portGetTickCnt();
-//                ints->
+                uint32 time_now = portGetTickCnt();
+                inst->timeofTx = time_now;
+//                tdma_handler->waitForInf = TRUE;
+//                tdma_handler->discovery_mode = WAIT_INF_INIT;
+                tdma_handler->set_discovery_mode(tdma_handler, WAIT_INF_INIT, time_now);
+//                uint8 debug_msg[100];
+//				sprintf((char *)&debug_msg, "RTLS_DEMO_MSG_RNG_INIT -> success!!!");
+//				send_txmsgtousb((char *)&debug_msg);
+//				usb_run();
                 //inst->monitor = 1;
             }
 
             break;
         }
+        case TA_TXINF_WAIT_SEND :
+		{
+			//NOTE: handles INF_SUG, INF_INIT, INF_UPDATE, and INF_REG
+
+			int psduLength = tdma_handler->infMessageLength; //TODO check all instances of this and dont send messages with zero psduLength! Will cause the UWB to lockup!
+
+			inst->inf_msg.seqNum = inst->frameSN++;
+
+			//update time since frame start!
+			tdma_handler->update_inf_tsfs(tdma_handler);
+
+
+			//would be best to store the results while populating the inf message
+		    //fcode + framelength + time since frame start + num_neighbors + 3*num_neightbors + 2*framelength
+//		    int num_neighbors = instfindnumactiveneighbors(inst);
+//		    int inf_msg_len = 1 + 1 + 4 + 1 + 3*num_neighbors + 2*tdma_handler->uwbListTDMAInfo[0].framelength;
+
+//#if (USING_64BIT_ADDR==1)
+////			psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;
+//			psduLength = inf_msg_len + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC;
+//#else
+////			psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+//			psduLength = inf_msg_len + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+//#endif
+
+			//set the delayed rx on time (the response message will be sent after this delay)
+			dwt_setrxaftertxdelay(inst->txToRxDelayTag_sy*0); //TODO fix this! remove *0
+			dwt_setrxtimeout((uint16)inst->fwtoTime_sy*2);    //TODO fix this! remove *2
+
+			dwt_writetxdata(psduLength, (uint8 *)  &inst->inf_msg, 0) ; // write the frame data
+
+			//response is not expected
+			inst->wait4ack = 0;
+
+//			uint32 dt = get_dt32(inst->buildFrameTime, portGetTickCnt());
+
+
+			dwt_writetxfctrl(psduLength, 0, 1);
+			if(dwt_starttx(DWT_START_TX_IMMEDIATE) == 0){
+				uint8 debug_msg[100];
+				int n = sprintf((char *)&debug_msg, "TX_INF - success!");//,%llX, psdu: %d ", instance_get_addr(), psduLength);
+				send_usbmessage(&debug_msg[0], n);
+				usb_run();
+
+				//if we successfully send out INF_INIT, INF_SUG, or INF_UPDATE, switch to INF_REG
+				//get the message FCODE
+				uint8 fcode;
+				memcpy(&fcode, &inst->inf_msg.messageData[FCODE], sizeof(uint8));
+
+
+				if(fcode == RTLS_DEMO_MSG_INF_SUG)
+				{
+					inst->nextState = TA_RXE_WAIT;
+				}
+				else
+				{
+					inst->nextState = TA_TXPOLL_WAIT_SEND;
+				}
+
+
+				if(fcode == RTLS_DEMO_MSG_INF_INIT ||
+				   fcode == RTLS_DEMO_MSG_INF_SUG ||
+				   fcode == RTLS_DEMO_MSG_INF_UPDATE)
+				{
+					fcode = RTLS_DEMO_MSG_INF_REG;
+					memcpy(&inst->inf_msg.messageData[FCODE], &fcode, sizeof(uint8));
+				}
+			}
+			else
+			{
+//				uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "TX_INF - fail!");//,%llX, psdu: %d ", instance_get_addr(), psduLength);
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
+			}
+
+			inst->testAppState = TA_TX_WAIT_CONF ;                                          // wait confirmation
+			inst->previousState = TA_TXINF_WAIT_SEND ;
+			done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below)
+
+			inst->timeofTx = portGetTickCnt();
+
+			break;
+		}
+//		//TODO fold TA_TXSUG_WAIT_SEND into INF_WAIT_SEND if possible
+//        case TA_TXSUG_WAIT_SEND : //TODO need a timeout from this avenue of operations
+//        {
+////        	send_txmsgtousb("TA_TXSUG_WAIT_SEND");
+////			uint8 debug_msg[100];
+////			int n = sprintf((char *)&debug_msg, "TA_TXSUG_WAIT_SEND!!!");
+////			send_usbmessage(&debug_msg[0], n);
+////			usb_run();
+//
+//			int psduLength = 0;
+//
+//			inst->inf_msg.seqNum = inst->frameSN++;
+//
+//			//TODO include some defines
+//			//fcode + framelength + time since frame start + num_neighbors + 3*num_neightbors + 2*framelength
+//			int num_neighbors = instfindnumactiveneighbors(inst);
+//			int inf_msg_len = 1 + 1 + 4 + 1 + 3*num_neighbors + 2*tdma_handler->uwbListTDMAInfo[0].framelength;
+//
+//#if (USING_64BIT_ADDR==1)
+////			psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;
+//			psduLength = inf_msg_len + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC;
+//#else
+////			psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+//			psduLength = inf_msg_len + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+//#endif
+//
+//			//set the delayed rx on time (the response message will be sent after this delay)
+//			dwt_setrxaftertxdelay(inst->txToRxDelayTag_sy*0); //TODO fix this! remove *0
+//			dwt_setrxtimeout((uint16)inst->fwtoTime_sy*2);    //TODO fix this! remove *2
+//
+//			dwt_writetxdata(psduLength, (uint8 *)  &inst->inf_msg, 0) ; // write the frame data
+//
+//			//response is not expected
+//			inst->wait4ack = 0;
+//
+////			uint32 dt = get_dt32(inst->buildFrameTime, portGetTickCnt());
+//
+//			uint8 debug_msg[100];
+//			int n = sprintf((char *)&debug_msg, "TX_INF_SUG, %llX", instance_get_addr());
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
+//
+//			dwt_writetxfctrl(psduLength, 0, 1);
+//			if(dwt_starttx(DWT_START_TX_IMMEDIATE) == 0){
+//				uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "TX_INF_SUG, success");
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
+//			}
+//			else
+//			{
+//				uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "TX_INF_SUG, fail");//,%llX, psdu: %d ", instance_get_addr(), psduLength);
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
+//			}
+//
+////			inst->testAppState = TA_TX_WAIT_CONF ;                                          // wait confirmation
+//			inst->previousState = TA_TXSUG_WAIT_SEND ;
+////			done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below)
+//
+////			inst->timeofTx = portGetTickCnt();
+//
+//			break;
+//        }
         case TA_TXPOLL_WAIT_SEND :
         {
 //            uint8 debug_msg[100];
 //            sprintf((char *)&debug_msg, "RTLS_DEMO_MSG_TAG_POLL -> uwb %i ", inst->uwbToRangeWith);
 //            send_txmsgtousb((char *)&debug_msg);
-            int psduLength = 0;
+
+        	//if here, we have already sent RTLS_DEMO_MSG_INF_INIT
+//        	inst->inf_msg.messageData[FCODE] = RTLS_DEMO_MSG_INF_SUG; //TODO make sure this is right
+
+        	int psduLength = 0;
             
             inst->goToSleep = 1; //go to Sleep after this poll
 
-            inst->msg[inst->uwbToRangeWith].seqNum = inst->frameSN++;
-            inst->msg[inst->uwbToRangeWith].messageData[FCODE] = RTLS_DEMO_MSG_TAG_POLL; //message function code (specifies if message is a poll, response or other...)
+//            inst->msg[inst->uwbToRangeWith].seqNum = inst->frameSN++;
+//            inst->msg[inst->uwbToRangeWith].messageData[FCODE] = RTLS_DEMO_MSG_TAG_POLL; //message function code (specifies if message is a poll, response or other...)
+            inst->msg.seqNum = inst->frameSN++;
+			inst->msg.messageData[FCODE] = RTLS_DEMO_MSG_TAG_POLL; //message function code (specifies if message is a poll, response or other...)
+			//TODO check where I am setting the destination address
 
-            instanceconfigframeheader(inst);
+//            instanceconfigframeheader(inst);
 
 #if (USING_64BIT_ADDR==1)
             psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;
 #else
             psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
 #endif
+
+
+
+//            for(int d = 1; d < 1000; d++){
+////            	psduLength++;
+//				uint8 dummy_data = 1;
+//				//add some dummy data to the poll to see how it affects timing
+//				memcpy(&inst->msg[inst->uwbToRangeWith].messageData[d], &dummy_data, 1);
+//
+//            }
+
+
             //set the delayed rx on time (the response message will be sent after this delay)
             dwt_setrxaftertxdelay(inst->txToRxDelayTag_sy*0); //TODO fix this! remove *0
             dwt_setrxtimeout((uint16)inst->fwtoTime_sy*2);    //TODO fix this! remove *2
 
-            dwt_writetxdata(psduLength, (uint8 *)  &inst->msg[inst->uwbToRangeWith], 0) ; // write the frame data
+//            dwt_writetxdata(psduLength, (uint8 *)  &inst->msg[inst->uwbToRangeWith], 0) ; // write the frame data
+            dwt_writetxdata(psduLength, (uint8 *)  &inst->msg, 0) ; // write the frame data
 
             //response is expected
             inst->wait4ack = DWT_RESPONSE_EXPECTED;
@@ -640,27 +956,27 @@ int testapprun(instance_data_t *inst, int message)
 				send_usbmessage(&debug_msg[0], n);
 				usb_run();
 
-				uint8 buffer[SYS_STATUS_LEN];
-				uint64 sys_status_reg;
-				dwt_readfromdevice(SYS_STATUS_ID,0,SYS_STATUS_LEN,buffer);
-
-				for (int j = SYS_STATUS_LEN-1 ; j >= 0 ; j --)
-				{
-					sys_status_reg = (sys_status_reg << 8) + buffer[j] ;
-				}
-
-				uint64 sys_state_reg;
-				dwt_readfromdevice(SYS_STATE_ID,0,SYS_STATE_LEN,buffer);
-
-				for (int j = SYS_STATE_LEN-1 ; j >= 0 ; j --)
-				{
-					sys_state_reg = (sys_state_reg << 8) + buffer[j] ;
-				}
+//				uint8 buffer[SYS_STATUS_LEN];
+//				uint64 sys_status_reg;
+//				dwt_readfromdevice(SYS_STATUS_ID,0,SYS_STATUS_LEN,buffer);
+//
+//				for (int j = SYS_STATUS_LEN-1 ; j >= 0 ; j --)
+//				{
+//					sys_status_reg = (sys_status_reg << 8) + buffer[j] ;
+//				}
+//
+//				uint64 sys_state_reg;
+//				dwt_readfromdevice(SYS_STATE_ID,0,SYS_STATE_LEN,buffer);
+//
+//				for (int j = SYS_STATE_LEN-1 ; j >= 0 ; j --)
+//				{
+//					sys_state_reg = (sys_state_reg << 8) + buffer[j] ;
+//				}
 
 //				debug_msg[100];
-				n = sprintf((char *)&debug_msg, "SYS_STATUS: %llu SYS_STATE: %llu", sys_status_reg, sys_state_reg);
-				send_usbmessage(&debug_msg[0], n);
-				usb_run();
+//				n = sprintf((char *)&debug_msg, "SYS_STATUS: %llu SYS_STATE: %llu", sys_status_reg, sys_state_reg);
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
 
             }
 
@@ -704,14 +1020,17 @@ int testapprun(instance_data_t *inst, int message)
         }
         case TA_TXFINAL_WAIT_SEND :
         {
+        	dwt_setrxaftertxdelay((uint16)0);
+			dwt_setrxtimeout((uint16)0);
+
+
             int psduLength = 0;
             // Embbed into Final message:40-bit respRxTime
             // Write Response RX time field of Final message
-            memcpy(&(inst->msg[inst->uwbToRangeWith].messageData[RRXT]), (uint8 *)&inst->anchorRespRxTime, 5);
-
-            inst->msg[inst->uwbToRangeWith].messageData[FCODE] = RTLS_DEMO_MSG_TAG_FINAL; //message function code (specifies if message is a poll, response or other...)
-
-            instanceconfigframeheader(inst);
+//            memcpy(&(inst->msg[inst->uwbToRangeWith].messageData[RRXT]), (uint8 *)&inst->anchorRespRxTime, 5);
+//            inst->msg[inst->uwbToRangeWith].messageData[FCODE] = RTLS_DEMO_MSG_TAG_FINAL; //message function code (specifies if message is a poll, response or other...)
+            memcpy(&(inst->msg.messageData[RRXT]), (uint8 *)&inst->anchorRespRxTime, 5);
+            inst->msg.messageData[FCODE] = RTLS_DEMO_MSG_TAG_FINAL; //message function code (specifies if message is a poll, response or other...)
             
 #if (USING_64BIT_ADDR==1)
             psduLength = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;
@@ -719,16 +1038,23 @@ int testapprun(instance_data_t *inst, int message)
             psduLength = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
 #endif
 
-            dwt_writetxdata(psduLength, (uint8 *)  &inst->msg[inst->uwbToRangeWith], 0) ; // write the frame data
+//            dwt_writetxdata(psduLength, (uint8 *)  &inst->msg[inst->uwbToRangeWith], 0) ; // write the frame data
+            dwt_writetxdata(psduLength, (uint8 *)  &inst->msg, 0) ; // write the frame data
 
-            uint32 response_time = portGetTickCnt() - inst->range_start;
+//            uint32 response_time = portGetTickCnt() - inst->range_start;
 
 //            uint16 reg = dwt_read16bitoffsetreg(PMSC_ID, 0) ;
 //			reg |= 0x20 ; // set bit 5 high
 //			dwt_write16bitoffsetreg(PMSC_ID, 0, reg) ;
 
-            if(instancesendpacket(psduLength, DWT_START_TX_DELAYED, inst->delayedReplyTime))
-            {
+            //response is expected
+//			inst->wait4ack = DWT_RESPONSE_EXPECTED;
+			inst->wait4ack = 0;
+//			dwt_writetxfctrl(psduLength, 0, 1); //TODO may need this...
+
+//            if(instancesendpacket(psduLength, DWT_START_TX_DELAYED, inst->delayedReplyTime))
+			if(instancesendpacket(psduLength, DWT_START_TX_DELAYED | inst->wait4ack, inst->delayedReplyTime))
+			{
                 // initiate the re-transmission
                 inst->testAppState = TA_TXE_WAIT ;
                 //inst->nextState = TA_TXPOLL_WAIT_SEND ; //TODO should this go to TX_SELECT instead?
@@ -738,40 +1064,114 @@ int testapprun(instance_data_t *inst, int message)
                 inst->wait4ack = 0; //clear the flag as the TX has failed the TRX is off
                 inst->lateTX++;
 
-//
+
                 uint8 debug_msg[100];
 				sprintf((char *)&debug_msg, "RTLS_DEMO_MSG_TAG_FINAL -> late tx");
 				send_txmsgtousb((char *)&debug_msg);
 				usb_run();
 
+//				 int n = sprintf((char*)&debug_msg[0], "time_now: %lu, replytime: %lu", dwt_readsystimestamphi32(), inst->delayedReplyTime);
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
+
             }
             else
             {
                 
-                inst->testAppState = TA_TX_WAIT_CONF;                                               // wait confirmation
+                inst->testAppState = TA_TX_WAIT_CONF;  // wait confirmation
                 inst->previousState = TA_TXFINAL_WAIT_SEND;
                 done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out  (set below)
                 
                 inst->timeofTx = portGetTickCnt();
                 inst->monitor = 1;
 
-               uint8 debug_msg[100];
-				sprintf((char *)&debug_msg, "RTLS_DEMO_MSG_TAG_FINAL -> success!");
-				send_txmsgtousb((char *)&debug_msg);
-				usb_run();
+//               uint8 debug_msg[100];
+//				sprintf((char *)&debug_msg, "RTLS_DEMO_MSG_TAG_FINAL -> success!");
+//				send_txmsgtousb((char *)&debug_msg);
+//				usb_run();
             }
-//            uint8 debug_msg[100];
-//			 int n = sprintf((char*)&debug_msg[0], "time_now: %lu, replytime: %lu", dwt_readsystimestamphi32(), inst->delayedReplyTime);
-//			 send_usbmessage(&debug_msg[0], n);
-//			 usb_run();
 
+            break;
+        }
+        case TA_TXREPORT_WAIT_SEND :
+		{
+
+			//set the delayed rx on time (the response message will be sent after this delay)
+//			dwt_setrxaftertxdelay(inst->txToRxDelayTag_sy*0); //TODO fix this! remove *0
+//			dwt_setrxtimeout((uint16)inst->fwtoTime_sy*2);    //TODO fix this! remove *2
+			dwt_setrxaftertxdelay((uint16)0);
+			dwt_setrxtimeout((uint16)0);
+
+//			dwt_writetxfctrl(psduLength, 0, 1);
+//			if(dwt_starttx(DWT_START_TX_IMMEDIATE) == 0){
+//	//				uint8 debug_msg[100];
+//	//				int n = sprintf((char *)&debug_msg, "TX_INF,%llX, psdu: %d ", instance_get_addr(), psduLength);
+//	//				send_usbmessage(&debug_msg[0], n);
+//	//				usb_run();
+//			}
+//
+//			inst->testAppState = TA_TX_WAIT_CONF ;                                          // wait confirmation
+//			inst->previousState = TA_TXINF_WAIT_SEND ;
+//			done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below)
+//
+//			inst->timeofTx = portGetTickCnt();
+//
 
 
+			int psduLength = 0;
 
-            break;
-        }
+			inst->report_msg.seqNum = inst->frameSN++;
+
+#if (USING_64BIT_ADDR==1)
+			psduLength = RNG_REPORT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC;
+#else
+			psduLength = RNG_REPORT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+#endif
+
+
+
+			//TODO if tof not zero, set tof, else memset 0
+			// Write calculated TOF into response message
+			//TODO #define messageData offsets
+//			memcpy(&inst->msg[inst->uwbToRangeWith].messageData[1], &inst->tof[inst->uwbToRangeWith], 6); //TODO fix number of bytes...
+//			dwt_writetxdata(psduLength, (uint8 *)  &inst->msg[inst->uwbToRangeWith], 0) ; // write the frame data
+			memcpy(&inst->report_msg.messageData[1], &inst->tof[inst->uwbToRangeWith], 6); //TODO fix number of bytes...
+			dwt_writetxdata(psduLength, (uint8 *)  &inst->report_msg, 0) ; // write the frame data
+
+			inst->wait4ack = 0;
+
+			if(instancesendpacket(psduLength, DWT_START_RX_IMMEDIATE, 0))
+			{
+				// initiate the re-transmission
+				inst->testAppState = TA_TXE_WAIT ;
+				inst->nextState = TA_RXE_WAIT; //TODO reset next and previous?
+
+				inst->wait4ack = 0; //clear the flag as the TX has failed the TRX is off
+				inst->lateTX++;
+
+			}
+			else
+			{
+//				uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "TX_RNG_REPORT");
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
+
+				inst->testAppState = TA_TX_WAIT_CONF;                                               // wait confirmation
+				inst->previousState = TA_TXREPORT_WAIT_SEND;
+				done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out  (set below)
+
+				inst->timeofTx = portGetTickCnt();
+				inst->monitor = 1;
+
+			}
+
+			break;
+		}
         case TA_TX_WAIT_CONF :
         {
+        	//TODO look at this state again. it seems to sometimes be problematic
+
             // if (inst->mode == ANCHOR)
             // {
 //                 send_statetousb(inst);
@@ -786,54 +1186,74 @@ int testapprun(instance_data_t *inst, int message)
                 if(dw_event->type == DWT_SIG_RX_TIMEOUT) //got RX timeout - i.e. did not get the response (e.g. ACK)
                 {
                     //we need to wait for SIG_TX_DONE and then process the timeout and re-send the frame if needed
+//                	uint8 debug_msg[100];
+//					int n = sprintf((char *)&debug_msg, "DWT_SIG_RX_TIMEOUT");
+//					send_usbmessage(&debug_msg[0], n);
+//					usb_run();
                     inst->gotTO = 1;
                 }
 
                 done = INST_DONE_WAIT_FOR_NEXT_EVENT;
 
-
                 //TODO maybe move out of this if statement???
                 //sometimes the DW1000 tx callback (TXFRS) fails to trigger and the the SYS_STATE register
                 //reads IDLE for for PMSC, RX, and TX so we need another way to timeout since RX FWTO won't be triggered.
-                uint32 dt = get_dt32(inst->timeofTx, portGetTickCnt());
-
-                if( inst->previousState == TA_TXFINAL_WAIT_SEND ||
-                    inst->previousState == TA_TXPOLL_WAIT_SEND ||
-                    inst->previousState == TA_TXRESPONSE_WAIT_SEND)
-                {
-                    //NOTE timeout duration found experimentally, may need to be changed if the delays in instance.h are modified
-                    if(dt > 20)
-                    {
-                        inst->gotTO = 1;
-                    }                
-                }
-                else if(inst->previousState == TA_TXBLINK_WAIT_SEND){ //TODO put this back above???
-                	if(dt > BLINK_SLEEP_DELAY + 20)
-					{
-						inst->gotTO = 1;
-					}
-                }
-                else if(inst->previousState == TA_TXRANGINGINIT_WAIT_SEND)
+//                uint32 dt = get_dt32(inst->timeofTx, portGetTickCnt());
+
+//                if( inst->previousState == TA_TXFINAL_WAIT_SEND ||
+//                    inst->previousState == TA_TXPOLL_WAIT_SEND ||
+//                    inst->previousState == TA_TXRESPONSE_WAIT_SEND ||
+//                    inst->previousState == TA_TXINF_WAIT_SEND)
+//                {
+//                    //NOTE timeout duration found experimentally, may need to be changed if the delays in instance.h are modified
+//                    if(dt > 200)
+//                    {
+//                        inst->gotTO = 1;
+//                		  //inst_processtxrxtimeout(inst);
+//                    }
+//                }
+//                else if(inst->previousState == TA_TXBLINK_WAIT_SEND){ //TODO put this back above???
+//                	if(dt > BLINK_SLEEP_DELAY + 20)
+//					{
+//						inst->gotTO = 1;
+//						//inst_processtxrxtimeout(inst);
+//
+//					}
+//                }
+//                else if(inst->previousState == TA_TXRANGINGINIT_WAIT_SEND)
+//                {
+//                    if(dt > RNG_INIT_REPLY_DLY_MS + 20)
+//                    {
+//                		//inst_processtxrxtimeout(inst);
+//                    	inst->gotTO = 1;
+//                    }
+//                }
+//
+                if(inst->gotTO == 0)
                 {
-                    if(dt > RNG_INIT_REPLY_DLY_MS + 20)
-                    {
-                    	inst->gotTO = 1;
-                    }
+                	break;
                 }
-                
-                break;
             }
 
             done = INST_NOT_DONE_YET;
 
+
             if (inst->gotTO) //timeout
 			{
-            	uint8 debug_msg[100];
-				int n = sprintf((char *)&debug_msg, "inst->gotTO");
-				send_usbmessage(&debug_msg[0], n);
-				usb_run();
+//            	uint32 mask = dwt_read32bitreg(SYS_MASK_ID);
+
+
+//            	uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "inst->gotTO, SYS_MASK: %lu", mask);
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
 				// send_txmsgtousb("(2nd) got TO in TA_TX_WAIT_CONF");
-				inst_processtxrxtimeout(inst);
+
+//            	uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "inst_processtxrxtimeout(inst) after inst->gotTO");
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
+            	inst_processtxrxtimeout(inst);
 				inst->gotTO = 0;
 				inst->wait4ack = 0 ; //clear this
 
@@ -842,34 +1262,19 @@ int testapprun(instance_data_t *inst, int message)
             else if(inst->previousState == TA_TXFINAL_WAIT_SEND) //TAG operations
 			{
 
-            	//TODO is this in the wrong spot?
-            	//add cooldown node
-            	uint32 time_now = portGetTickCnt();
-				tx_timing_node *node = malloc(sizeof(tx_timing_node));
-				node->index = inst->uwbToRangeWith;
-				uint32 time_remaining = 0;
-				if(time_now < inst->tx_scheduler.expected_tx_end_time){
-					time_remaining = inst->tx_scheduler.expected_tx_end_time - time_now;
-				}
-				node->duration = (inst->uwbNumActive[inst->uwbToRangeWith]-1)*(uint32)RANGE_DURATION_MS + time_remaining+20;
-
-//				node->duration = (inst->uwbNumActive[inst->uwbToRangeWith]-1)*(int)RANGE_DURATION_MS + inst->tx_scheduler.time_reject_select - time_now;
-				node->time = time_now;
-
-				inst->tx_scheduler.add_node(&inst->tx_scheduler, node);
-
-//				uint8 debug_msg[100];
-//				int n = sprintf((char *)&debug_msg, "tx_scheduler add_node duration %lu", node->duration);
-//				send_usbmessage(&debug_msg[0], n);
-//				usb_run();
+//                inst->testAppState = TA_TXE_WAIT ;
+//                inst->nextState = TA_TX_SELECT;
+            	inst->testAppState = TA_RXE_WAIT;
 
-                inst->testAppState = TA_TXE_WAIT ;
-                inst->nextState = TA_TX_SELECT;
-//                inst->uwbToRangeWith = instfindfirstactiveuwbinlist(inst, inst->uwbToRangeWith + 1);
-                
                 break;
             }
-            else 
+            else if(inst->previousState == TA_TXINF_WAIT_SEND)
+            {
+            	inst->testAppState = inst->nextState;
+
+            	break;
+            }
+            else
             {
                 inst->txu.txTimeStamp = dw_event->timeStamp;
 
@@ -888,11 +1293,20 @@ int testapprun(instance_data_t *inst, int message)
                     tagCalculatedFinalTxTime = tagCalculatedFinalTxTime + inst->txAntennaDelay;
                     tagCalculatedFinalTxTime &= MASK_40BIT;
 
+//                    // Write Calculated TX time field of Final message
+//                    memcpy(&(inst->msg[inst->uwbToRangeWith].messageData[FTXT]), (uint8 *)&tagCalculatedFinalTxTime, 5);
+//                    // Write Poll TX time field of Final message
+//                    memcpy(&(inst->msg[inst->uwbToRangeWith].messageData[PTXT]), (uint8 *)&inst->txu.tagPollTxTime, 5);
                     // Write Calculated TX time field of Final message
-                    memcpy(&(inst->msg[inst->uwbToRangeWith].messageData[FTXT]), (uint8 *)&tagCalculatedFinalTxTime, 5);
-                    // Write Poll TX time field of Final message
-                    memcpy(&(inst->msg[inst->uwbToRangeWith].messageData[PTXT]), (uint8 *)&inst->txu.tagPollTxTime, 5);
+					memcpy(&(inst->msg.messageData[FTXT]), (uint8 *)&tagCalculatedFinalTxTime, 5);
+					// Write Poll TX time field of Final message
+					memcpy(&(inst->msg.messageData[PTXT]), (uint8 *)&inst->txu.tagPollTxTime, 5);
+
                 }
+//                else if(inst->previousState == TA_TXRANGINGINIT_WAIT_SEND)
+//                {
+//                	inst->mode = ANCHOR;
+//                }
 
                 inst->testAppState = TA_RXE_WAIT ;       // After sending, tag expects response/report, anchor waits to receive a final/new poll
                 
@@ -911,10 +1325,10 @@ int testapprun(instance_data_t *inst, int message)
             {
                 //turn RX on
 
-            	uint8 debug_msg[100];
-				 int n = sprintf((char*)&debug_msg[0], "instancerxon called from  case TA_RXE_WAIT :");
-				 send_usbmessage(&debug_msg[0], n);
-				 usb_run();
+//            	uint8 debug_msg[100];
+//				 int n = sprintf((char*)&debug_msg[0], "instancerxon called from  case TA_RXE_WAIT :");
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
 
                 instancerxon(inst, 0, 0) ;   // turn RX on, without delay
             }
@@ -923,11 +1337,9 @@ int testapprun(instance_data_t *inst, int message)
                 inst->wait4ack = 0 ; //clear the flag, the next time we want to turn the RX on it might not be auto
             }
 
-            if (inst->mode != LISTENER)
-            {
-                //we are going to use anchor/tag timeout
-                done = INST_DONE_WAIT_FOR_NEXT_EVENT; //using RX FWTO
-            }
+
+			//we are going to use anchor/tag timeout
+			done = INST_DONE_WAIT_FOR_NEXT_EVENT; //using RX FWTO
 
             inst->testAppState = TA_RX_WAIT_DATA;   // let this state handle it
             inst->rxCheckOnTime = portGetTickCnt() + RX_CHECK_ON_PERIOD;
@@ -945,6 +1357,7 @@ int testapprun(instance_data_t *inst, int message)
             //     send_statetousb(inst);
             // }
 
+
             // Wait RX data
             switch (message)
             {
@@ -953,8 +1366,11 @@ int testapprun(instance_data_t *inst, int message)
 //                     send_rxmsgtousb("RX process: DWT_SIG_RX_BLINK ");
                     event_data_t* dw_event = instance_getevent(12); //get and clear this event
                     
-                    if((inst->mode == LISTENER) || (inst->mode == ANCHOR))
-                    {
+//                    if(inst->mode == ANCHOR)
+					if(inst->mode == DISCOVERY)
+					{
+						//inst->mode = ANCHOR; //TODO instead switch to anchor after sending out the ANCH_RESP
+
                         inst->canPrintInfo = 1;
 
                         //if using longer reply delay time (e.g. if interworking with a PC application)
@@ -1016,25 +1432,72 @@ int testapprun(instance_data_t *inst, int message)
                     {
                         case RTLS_DEMO_MSG_RNG_INIT:
                         {
+                        	//NOTE: WAIT_RNG_INIT checked in RX callback
+
 //                            send_rxmsgtousb("RX process: DWT_SIG_RX_OKAY-RTLS_DEMO_MSG_RNG_INIT");
-                            
-                        	uint8 debug_msg[100];
-							int n = sprintf((char *)&debug_msg, "BLINK_COMPLETE,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith));
-							send_usbmessage(&debug_msg[0], n);
-							usb_run();
+//                        	uint8 debug_msg[100];
+//                        	int n = sprintf((char *)&debug_msg, "BLINK_COMPLETE,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith));
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
 
                             uint32 final_reply_delay_us;
                             uint32 resp_dly[RESP_DLY_NB];
                             int i;
 
-                            inst->testAppState = TA_TXE_WAIT;
-                            inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll
+                            tdma_handler->build_new_network(tdma_handler);
+
+                            //build the initial TDMA
+//                            tdma_handler->uwbFrameStartTimes[0] = portGetTickCnt() - tdma_handler->slotDuration;//TODO handle timer wrapping...
+//                            tdma_handler->lastSlotStartTime = portGetTickCnt();
+//                            tdma_handler->uwbListTDMAInfo[0].framelength = (uint8)MIN_FRAMELENGTH;
+//
+//
+//                            //todo: make this a handler function
+//							//new
+//							tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[0], 1);
+//							tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith],  2);
+////							tdma_handler->uwblist_assign_slot(tdma_handler, 0,  2);
+//							tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[0], 3);
+
+							//TODO build slotAssignment array
+
+//							bool assigned0 = tdma_handler->slot_assigned(tdma_handler, 0);
+//							bool assigned1 = tdma_handler->slot_assigned(tdma_handler, 1);
+//							bool assigned2 = tdma_handler->slot_assigned(tdma_handler, 2);
+//							bool assigned3 = tdma_handler->slot_assigned(tdma_handler, 3);
+//
+//							uint8 debug_msg[100];
+//							int n = sprintf((char*)&debug_msg[0], "ass0: %u, ass1: %u, ass2: %u, ass3: %u,", assigned0, assigned1, assigned2, assigned3);
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
+
+
+//							tdma_handler->usb_dump_tdma(tdma_handler);
+
+//							inst->inf_msg.messageData[FCODE] = RTLS_DEMO_MSG_INF_INIT;
+                            tdma_handler->populate_inf_msg(tdma_handler, RTLS_DEMO_MSG_INF_INIT);
+
+							uint32 time_now = portGetTickCnt();
+							tdma_handler->set_discovery_mode(tdma_handler, EXIT, time_now);
+
+							inst->buildFrameTime = time_now;
+//							n = sprintf((char *)&debug_msg, "BUILD FRAME,time_now: %lu, framestart: %lu, slotduration: %lu", portGetTickCnt(), tdma_handler->frameStartTime, tdma_handler->slotDuration);
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
+
+//                            inst->testAppState = TA_TXE_WAIT;
+							inst->testAppState = TA_TX_SELECT;
+//                            inst->testAppState = TA_TXINF_WAIT_SEND;
+//                            inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll
+//                            inst->nextState = TA_TXINF_WAIT_SEND ; // send next poll
+
 
                             // Get response delays from message and update internal timings accordingly
                             resp_dly[RESP_DLY_ANC] =  messageData[RNG_INIT_ANC_RESP_DLY_LO]
                                                         + (messageData[RNG_INIT_ANC_RESP_DLY_HI] << 8);
                             resp_dly[RESP_DLY_TAG] =  messageData[RNG_INIT_TAG_RESP_DLY_LO]
                                                         + (messageData[RNG_INIT_TAG_RESP_DLY_HI] << 8);
+
                             for (i = 0; i < RESP_DLY_NB; i++)
                             {
                                 if (((resp_dly[i] & RESP_DLY_UNIT_MASK) >> RESP_DLY_UNIT_SHIFT) == RESP_DLY_UNIT_MS)
@@ -1061,28 +1524,183 @@ int testapprun(instance_data_t *inst, int message)
                                 inst->sleepingEabled = 0;
                             }
 
-                            memcpy(&inst->msg[inst->uwbToRangeWith].destAddr[0], &srcAddr[0], inst->addrByteSize); //set the anchor address for the reply (set destination address)
+//                            memcpy(&inst->msg[inst->uwbToRangeWith].destAddr[0], &srcAddr[0], inst->addrByteSize); //set the anchor address for the reply (set destination address)
+                            memcpy(&inst->msg.destAddr[0], &srcAddr[0], inst->addrByteSize); //set the anchor address for the reply (set destination address)
 
-//                            inst->mode = TAG ;
+                            inst->mode = TAG;
                             //inst->responseTimeouts = 0; //reset timeout count
                             inst->goToSleep = 0; //don't go to sleep - start ranging instead and then sleep after 1 range is done or poll times out
                             inst->instanceTimerTimeSaved = inst->instanceTimerTime = portGetTickCnt(); //set timer base
                         
                             break; 
                         } //RTLS_DEMO_MSG_RNG_INIT
-                        case RTLS_DEMO_MSG_TAG_POLL:
+                        case RTLS_DEMO_MSG_INF_UPDATE : //fall through
+                        case RTLS_DEMO_MSG_INF_SUG :    //fall through
+                        case RTLS_DEMO_MSG_INF_REG :
                         {
-                            if(inst->mode == LISTENER) //don't process any ranging messages when in Listener mode
-                            {
-                                //only enable receiver when not using double buffering
-                                inst->testAppState = TA_RXE_WAIT ;  // wait for next frame
-                                break;
-                            }
+//							uint32 time_now = portGetTickCnt();
+//							uint8 srcIndex = instgetuwblistindex(inst, &srcAddr[0], inst->addrByteSize);
+//
+//                        	if(inst->mode == DISCOVERY)
+//                        	{
+//                        		//NOTE: RX callback only accepts INF_UPDATE/INF_SUG/INF_REG for discovery modes WAIT_INF_REG and COLLECT_INF_REG.
+//
+//                        		//1.) sync our frame start time to the local network
+//                        		//2.) collect and combine tdma info so we can construct a SUG packet and send it out
+//
+//                        		if(tdma_handler->discovery_mode == WAIT_INF_REG) //treat INF_UPDATE and INF_SUG the same
+//								{
+//                        			//synchronize the frames
+//                        			tdma_handler->frame_sync(tdma_handler, dw_event, messageData, srcIndex, FS_ADOPT);
+////                        			//initialize collection of tdma info, clear any previously stored info
+////                        			tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, CLEAR_ALL_COPY);
+////                        			//set discovery mode to COLLECT_INF_REG
+////                        			tdma_handler->set_discovery_mode(tdma_handler, COLLECT_INF_REG, time_now);
+//								}
+//                        		else if(tdma_handler->discovery_mode == COLLECT_INF_REG)
+//                        		{
+//                        			//synchronize the frames
+//									tdma_handler->frame_sync(tdma_handler, dw_event, messageData, srcIndex, FS_AVERAGE);
+////                        			//collecting tdma info, append to previously stored info
+////                        			tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, COPY);
+//                        		}
+//                        	}
+//                        	else if(inst->mode == ANCHOR || inst->mode == TAG)
+//                        	{
+//                        		//if we are a TAG or ANCHOR
+//								//1.) sync our frame start time to the local network
+//                        		//2.) check for and adopt any tdma changes, sending an INF_UPDATE or INF_REG accordingly
+//
+//                        		//synchronize the frames
+//								tdma_handler->frame_sync(tdma_handler, dw_event, messageData, srcIndex, FS_AVERAGE);
+//
+//								//collecting tdma info, append to previously stored info
+////								bool tdma_modified = tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, CLEAR_LISTED_COPY);
+////
+////								if(tdma_modified)
+////								{
+////									//TODO set some sort of flag that tells us to send INF_UPDATE!!!
+////									tdma_handler->populate_inf_msg(tdma_handler, RTLS_DEMO_MSG_INF_UPDATE);
+////								}
+//
+//								//clear all tdma information
+//								tdma_handler->tdma_free_all_slots(tdma_handler);
+//
+//								//build the initial TDMA
+//								tdma_handler->uwbListTDMAInfo[0].framelength = (uint8)MIN_FRAMELENGTH;
+//								tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith].framelength = (uint8)MIN_FRAMELENGTH;
+//
+//								tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith], 1);
+//								tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[0],  2);
+//								tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith], 3);
+//
+//								tdma_handler->populate_inf_msg(tdma_handler, RTLS_DEMO_MSG_INF_UPDATE);
+//
+//								//TODO left off here! make sure the logic below is enforced in the RX callback
+//								//NOTE i can think of some differences between SUG/UPDATE/REG...
+//								//when waiting to send INF_SUG, ignore everything else?
+//								//when waiting to send INF_UPDATE, ignore INF_REG?
+//
+//
+//                        	}
+
+							//wait for next RX
+							inst->testAppState = TA_RXE_WAIT ;
+
+                        	break;
+                        }
+                        case RTLS_DEMO_MSG_INF_INIT :
+						{
+							//NOTE: discovery mode WAIT_INF_INIT checked in RX callback
+
+							//process the INF packet
+//							uint8 debug_msg[100];
+//							 int n = sprintf((char*)&debug_msg[0], "process RTLS_DEMO_MSG_INF :");
+//							 send_usbmessage(&debug_msg[0], n);
+//							 usb_run();
+
+							uint32 time_now = portGetTickCnt();
+							uint8 srcIndex = instgetuwblistindex(inst, &srcAddr[0], inst->addrByteSize);
+
+							//clear all tdma information
+							tdma_handler->tdma_free_all_slots(tdma_handler);
+
+							//build the initial TDMA
+							tdma_handler->uwbListTDMAInfo[0].framelength = (uint8)MIN_FRAMELENGTH;
+							tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith].framelength = (uint8)MIN_FRAMELENGTH;
+
+
+							//synchronise the frames
+							tdma_handler->frame_sync(tdma_handler, dw_event, messageData, srcIndex, FS_ADOPT);
+//							//initialize collection of tdma info, clear any previously stored info
+//							tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, CLEAR_ALL_COPY);
+							//set discovery mode to EXIT
+							tdma_handler->set_discovery_mode(tdma_handler, EXIT, time_now); //TODO do I really need EXIT?
+
+//							//collecting tdma info, append to previously stored info
+//							bool tdma_modified = tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, CLEAR_LISTED_COPY);
+//
+//							if(tdma_modified)
+//							{
+//								//TODO set some sort of flag that tells us to send INF_UPDATE!!!
+//								tdma_handler->populate_inf_msg(tdma_handler, RTLS_DEMO_MSG_INF_UPDATE);
+//							}
+
+
+							tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith], 1);
+							tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[0],  2);
+							tdma_handler->assign_slot(&tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith], 3);
+
+							tdma_handler->populate_inf_msg(tdma_handler, RTLS_DEMO_MSG_INF_UPDATE);
+
+
+
+							inst->mode = ANCHOR;
 
+							//stay in RX wait for next frame...
+							inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+
+							break;
+						}//RTLS_DEMO_MSG_INF
+//                        case RTLS_DEMO_MSG_INF_SUG :
+//						{
+//							//TODO: process differently depending on if we are or aren't in discovery
+//
+//							//process the INF_SUG packet and return to RX
+//							uint8 debug_msg[100];
+//							int n = sprintf((char*)&debug_msg[0], "process RTLS_DEMO_MSG_INF_SUG :");
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
+//
+////							uint8 srcIndex = instgetuwblistindex(inst, &srcAddr[0], inst->addrByteSize);
+////
+////							//synchronise the frames
+////							tdma_handler->frame_sync(tdma_handler, messageData, dw_event->rxLength, srcIndex, FS_ADOPT);
+////							//initialize collection of tdma info, clear any previously stored info
+////							tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, CLEAR_ALL_COPY);
+////							//set discovery mode to EXIT
+////							tdma_handler->set_discovery_mode(tdma_handler, EXIT, time_now); //TODO do I really need EXIT?
+//
+//
+//							uint8 srcIndex = instgetuwblistindex(inst, &srcAddr[0], inst->addrByteSize);
+//
+//							//TODO implement
+////							tdma_handler->process_sug_msg(tdma_handler, messageData, &srcAddr);
+//							tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, CLEAR_LISTED_COPY);
+//
+//							//TODO add frame sync!
+//
+//							//stay in RX wait for next frame...
+//							inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+//
+//							break;
+//						}//RTLS_DEMO_MSG_INF_SUG
+                        case RTLS_DEMO_MSG_TAG_POLL:
+                        {
                             if(dw_event->typePend == DWT_SIG_TX_PENDING)
                             {
                                 inst->canPrintInfo = 0;
-                                inst->testAppState = TA_TX_WAIT_CONF;                                               // wait confirmation
+                                inst->testAppState = TA_TX_WAIT_CONF;              // wait confirmation
                                 inst->previousState = TA_TXRESPONSE_WAIT_SEND ;
                             }
                             else
@@ -1096,53 +1714,31 @@ int testapprun(instance_data_t *inst, int message)
                         case RTLS_DEMO_MSG_ANCH_RESP:
                         {
 //                             send_rxmsgtousb("RX process: DWT_SIG_RX_OKAY-RTLS_DEMO_MSG_ANCH_RESP ");
-                            if(inst->mode == LISTENER) //don't process any ranging messages when in Listener mode
-                            {
-                                inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
-                                break;
-                            }
 
                             inst->anchorRespRxTime = dw_event->timeStamp ; //Response's Rx time
 
-                            uint32 dt = portGetTickCnt() - inst->timeofTx;
-							char debug_msg[100];
-							int n = sprintf((char*)&debug_msg[0], "time till ANCH_RESP %lu", dt);
-							send_usbmessage(&debug_msg[0], n);
-							usb_run();
+//                            uint32 dt = portGetTickCnt() - inst->timeofTx;
+//							char debug_msg[100];
+//							int n = sprintf((char*)&debug_msg[0], "time till ANCH_RESP %lu", dt);
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
 
                             inst->testAppState = TA_TXFINAL_WAIT_SEND ; // send our response / the final
 
-                            inst->canPrintInfo = 2;
-
-                            inst->tof[inst->uwbToRangeWith] = 0;
-                            //copy previously calculated ToF
-                            memcpy(&inst->tof[inst->uwbToRangeWith], &messageData[TOFR], 6);
-                            memcpy(&inst->uwbNumActive[inst->uwbToRangeWith], &messageData[NTAG], 1);
-
-                            uint32 time_till = 0;
-                            memcpy(&time_till, &messageData[TIME_TILL], sizeof(uint32));
-                            if(time_till != 0){
-
-                            	tx_timing_node *node = malloc(sizeof(tx_timing_node));
-								node->index = inst->uwbToRangeWith;
-								node->duration = 200; //TODO cleanup, set to blink window duration
-//								node->time = portGetTickCnt() - inst->tof[inst->uwbToRangeWith] + time_till; //TODO correctly implement (convert tof timescale?)
-								node->time = portGetTickCnt() + time_till;
-
-								inst->tx_scheduler.add_node(&inst->tx_scheduler, node);
-
-
-
-                            }
-
-
-                            inst->newRangeUWBIndex = inst->uwbToRangeWith;
-                            inst->newRangeAncAddress = instance_get_uwbaddr(inst->uwbToRangeWith);
-                            inst->newRangeTagAddress = instance_get_addr();
+//                            inst->canPrintInfo = 2;
+//
+//                            inst->tof[inst->uwbToRangeWith] = 0;
+//                            //copy previously calculated ToF
+//                            memcpy(&inst->tof[inst->uwbToRangeWith], &messageData[TOFR], 6);
+//                            memcpy(&inst->uwbNumActive[inst->uwbToRangeWith], &messageData[NTAG], 1);
+//
+//                            inst->newRangeUWBIndex = inst->uwbToRangeWith;
+//                            inst->newRangeAncAddress = instance_get_uwbaddr(inst->uwbToRangeWith);
+//                            inst->newRangeTagAddress = instance_get_addr();
 
                             break; 
-                        } //RTLS_DEMO_MSG_ANCH_RESP
-                        case RTLS_DEMO_MSG_TAG_FINAL:
+						} //RTLS_DEMO_MSG_ANCH_RESP
+                        case RTLS_DEMO_MSG_TAG_FINAL :
                         {
 //                            send_rxmsgtousb("RX process: DWT_SIG_RX_OKAY-RTLS_DEMO_MSG_TAG_FINAL ");
                             int64 Rb, Da, Ra, Db ;
@@ -1155,11 +1751,6 @@ int testapprun(instance_data_t *inst, int message)
                             double RbyDb = 0;
                             double RayDa = 0;
 
-                            if(inst->mode == LISTENER) //don't process any ranging messages when in Listener mode
-                            {
-                                inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
-                                break;
-                            }
 
                             // time of arrival of Final message
                             tagFinalRxTime = dw_event->timeStamp ; //Final's Rx time
@@ -1195,49 +1786,78 @@ int testapprun(instance_data_t *inst, int message)
 //							send_usbmessage(&debug_msg[0], n);
 //							usb_run();
 
-                            if(reportTOF(inst, inst->newRangeUWBIndex) == 0)
-                            {
-                                inst->newRange = 1;
-                            }
+                            if(inst->tof[inst->newRangeUWBIndex] > 0) //if ToF == 0 - then no new range to report
+		                    {
+		                        if(reportTOF(inst, inst->newRangeUWBIndex)==0)
+		                        {
+		                            inst->newRange = 1;
+		                            inst->ranging = 1;
+									inst->canPrintInfo = 1;
+		                        }
+		                    }
+
+                            inst->lastRangeTimeStamp[inst->uwbToRangeWith] = portGetTickCnt();
 
-                            //TODO update or remove?
-                            // inst->newRangeTagAddress = (uint16) srcAddr[0] + ((uint16) srcAddr[1] << 8);
-                            // inst->newRangeAncAddress = (uint16) inst->eui64[0] + ((uint16) inst->eui64[1] << 8);
                             inst->newRangeTagAddress = instance_get_uwbaddr(inst->uwbToRangeWith);
                             inst->newRangeAncAddress = instance_get_addr();
                             
-                            uint8 debug_msg[100];
-							int n = sprintf((char *)&debug_msg, "POLL_COMPLETE,%llX,%llX", inst->newRangeTagAddress, inst->newRangeAncAddress);
-							send_usbmessage(&debug_msg[0], n);
-							usb_run();
-
-                            //get num active
-                            rx_timing_node *node = malloc(sizeof(rx_timing_node));
-							node->index = inst->uwbToRangeWith;
-							uint32 num_active = 0;
-							for(int i = 0; i < inst->uwbListLen; i++)
+
+//							char debug_msg[100];
+//							n = sprintf((char*)&debug_msg[0], "TAG_FINAL %i", *node->index);
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
+
+                            inst->testAppState = TA_TXREPORT_WAIT_SEND;
+
+                            //TODO this changes! we need to send RNG_REPORT
+//                            inst->testAppState = TA_RXE_WAIT ;
+//                            inst->previousState = TA_INIT;
+//                            inst->nextState = TA_INIT;
+//                            inst->uwbToRangeWith = 255;
+//
+//                            dwt_setrxaftertxdelay(0);
+//							instancesetantennadelays(); //this will update the antenna delay if it has changed
+
+
+                            //char debug_msg[100];
+//							n = sprintf((char*)&debug_msg[0], "TAG_FINAL %d", inst->uwbToRangeWith);
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
+
+
+                            break; 
+                        } //RTLS_DEMO_MSG_TAG_FINAL
+                        case RTLS_DEMO_MSG_RNG_REPORT:
+						{
+//                             send_rxmsgtousb("RX process: DWT_SIG_RX_OKAY-RTLS_DEMO_MSG_RNG_REPORT ");
+
+
+                            inst->tof[inst->uwbToRangeWith] = 0;
+
+                            //copy previously calculated ToF
+                            //TODO #define messageData offsets
+                            memcpy(&inst->tof[inst->uwbToRangeWith], &messageData[1], 6);
+
+                            inst->newRangeUWBIndex = inst->uwbToRangeWith;
+                            inst->newRangeAncAddress = instance_get_uwbaddr(inst->uwbToRangeWith);
+                            inst->newRangeTagAddress = instance_get_addr();
+
+                            if(inst->tof[inst->newRangeUWBIndex] > 0) //if ToF == 0 - then no new range to report
 							{
-								if(inst->uwbTimeout[i] == 0)
+								if(reportTOF(inst, inst->newRangeUWBIndex)==0)
 								{
-									num_active++;
+									inst->newRange = 1;
+									inst->ranging = 1;
+									inst->canPrintInfo = 1;
 								}
 							}
-							uint32 time_now = portGetTickCnt();
-							uint32 time_remaining = 0;
-//							if(time_now < inst->rx_scheduler.time_reject_all){
-//								time_remaining = inst->rx_scheduler.time_reject_all - time_now;
-//							}
-							if(time_now < inst->rx_scheduler.accepted_node_end_time){
-								time_remaining = inst->rx_scheduler.accepted_node_end_time - time_now;
-							}
-							node->duration = (int)RANGE_DURATION_MS*(num_active-1) + time_remaining;
-							node->time = time_now;
-							node->type = RX_REJECT;
 
-							inst->rx_scheduler.add_node(&inst->rx_scheduler, node);
+                            inst->lastRangeTimeStamp[inst->uwbToRangeWith] = portGetTickCnt();
 
-//							char debug_msg[100];
-//							n = sprintf((char*)&debug_msg[0], "TAG_FINAL %i", *node->index);
+                            done = INST_DONE_WAIT_FOR_NEXT_EVENT;
+
+//                            uint8 debug_msg[100];
+//							int n = sprintf((char *)&debug_msg, "POLL_COMPLETE,%llX,%llX", inst->newRangeTagAddress, inst->newRangeAncAddress);
 //							send_usbmessage(&debug_msg[0], n);
 //							usb_run();
 
@@ -1250,15 +1870,8 @@ int testapprun(instance_data_t *inst, int message)
                             dwt_setrxaftertxdelay(0);
 							instancesetantennadelays(); //this will update the antenna delay if it has changed
 
-
-                            //char debug_msg[100];
-//							n = sprintf((char*)&debug_msg[0], "TAG_FINAL %d", inst->uwbToRangeWith);
-//							send_usbmessage(&debug_msg[0], n);
-//							usb_run();
-
-
-                            break; 
-                        } //RTLS_DEMO_MSG_TAG_FINAL
+							break;
+						} //RTLS_DEMO_MSG_RNG_REPORT
                         default:
                         {
 //                            if(inst->mode == ANCHOR)
@@ -1272,63 +1885,85 @@ int testapprun(instance_data_t *inst, int message)
                         }
                     } //end switch (fcode)
 
-                    if((inst->goToSleep == 0) && (inst->mode == LISTENER) /*|| (inst->mode == ANCHOR)*/)//update received data, and go back to receiving frames
-                    {
-                        inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
-
-                        dwt_setrxaftertxdelay(0);
-                    }
                 
                     break ; 
                 } //end of DWT_SIG_RX_OKAY
                 case DWT_SIG_RX_TIMEOUT :
                 {
+                	if(tdma_handler->discovery_mode == WAIT_RNG_INIT || tdma_handler->discovery_mode == WAIT_INF_INIT)
+					{
+//						tdma_handler->discovery_mode = WAIT_INF_REG;
+                		uint32 time_now = portGetTickCnt();
+						tdma_handler->set_discovery_mode(tdma_handler, WAIT_INF_REG, time_now);
+					}
+
+
 //                    send_txmsgtousb("RX process: DWT_SIG_RX_TIMEOUT ");
                     int n;
                     if(inst->previousState == TA_TXBLINK_WAIT_SEND)
 					{
-						uint8 debug_msg[100];
-						n = sprintf((char *)&debug_msg, "TX_BLINK_TIMEOUT,%llX,NULL", instance_get_addr());
-						send_usbmessage(&debug_msg[0], n);
-						usb_run();
+//                    	if(tdma_handler->discovery_mode == WAIT_RNG_INIT)
+//                    	{
+//                    		tdma_handler->discovery_mode = WAIT_INF_REG;
+//                    	}
+//                    	tdma_handler->waitForRngInit = FALSE;
+//						uint8 debug_msg[100];
+//						n = sprintf((char *)&debug_msg, "TX_BLINK_TIMEOUT,%llX,NULL", instance_get_addr());
+//						send_usbmessage(&debug_msg[0], n);
+//						usb_run();
+					}
+                    else if(inst->previousState == TA_TXRANGINGINIT_WAIT_SEND)
+                    {
+//                    	if(tdma_handler->discovery_mode == WAIT_INF_INIT)
+//                    	{
+//                    		tdma_handler->discovery_mode = WAIT_INF_REG;
+//                    	}
+//                    	tdma_handler->waitForInf = FALSE;
+                    }
+                    else if(inst->previousState == TA_TXINF_WAIT_SEND)
+					{
 					}
 					else if(inst->previousState == TA_TXFINAL_WAIT_SEND)
 					{
-						uint8 debug_msg[100];
-						n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith));
-						send_usbmessage(&debug_msg[0], n);
-						usb_run();
+//						uint8 debug_msg[100];
+//						n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith));
+//						send_usbmessage(&debug_msg[0], n);
+//						usb_run();
 					}
 					else if(inst->previousState == TA_TXPOLL_WAIT_SEND)
 					{
-						uint8 debug_msg[100];
-						n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith));
-						send_usbmessage(&debug_msg[0], n);
-						usb_run();
+//						uint8 debug_msg[100];
+//						n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith));
+//						send_usbmessage(&debug_msg[0], n);
+//						usb_run();
 					}
                     
-                    uint8 buffer[SYS_STATUS_LEN];
-					uint64 sys_status_reg;
-					dwt_readfromdevice(SYS_STATUS_ID,0,SYS_STATUS_LEN,buffer);
-
-					for (int j = SYS_STATUS_LEN-1 ; j >= 0 ; j --)
-					{
-						sys_status_reg = (sys_status_reg << 8) + buffer[j] ;
-					}
-
-					uint64 sys_state_reg;
-					dwt_readfromdevice(SYS_STATE_ID,0,SYS_STATE_LEN,buffer);
-
-					for (int j = SYS_STATE_LEN-1 ; j >= 0 ; j --)
-					{
-						sys_state_reg = (sys_state_reg << 8) + buffer[j] ;
-					}
+//                    uint8 buffer[SYS_STATUS_LEN];
+//					uint64 sys_status_reg;
+//					dwt_readfromdevice(SYS_STATUS_ID,0,SYS_STATUS_LEN,buffer);
+//
+//					for (int j = SYS_STATUS_LEN-1 ; j >= 0 ; j --)
+//					{
+//						sys_status_reg = (sys_status_reg << 8) + buffer[j] ;
+//					}
+//
+//					uint64 sys_state_reg;
+//					dwt_readfromdevice(SYS_STATE_ID,0,SYS_STATE_LEN,buffer);
+//
+//					for (int j = SYS_STATE_LEN-1 ; j >= 0 ; j --)
+//					{
+//						sys_state_reg = (sys_state_reg << 8) + buffer[j] ;
+//					}
 
-					uint8 debug_msg[100];
-					n = sprintf((char *)&debug_msg, "SYS_STATUS: %llu SYS_STATE: %llu", sys_status_reg, sys_state_reg);
-					send_usbmessage(&debug_msg[0], n);
-					usb_run();
+//					uint8 debug_msg[100];
+//					n = sprintf((char *)&debug_msg, "SYS_STATUS: %llu SYS_STATE: %llu", sys_status_reg, sys_state_reg);
+//					send_usbmessage(&debug_msg[0], n);
+//					usb_run();
 
+//                    uint8 debug_msg[100];
+//					n = sprintf((char *)&debug_msg, "inst_processtxrxtimeout(inst) after DWT_SIG_RX_TIMEOUT");
+//					send_usbmessage(&debug_msg[0], n);
+//					usb_run();
 
 
                     instance_getevent(17); //get and clear this event
@@ -1351,7 +1986,7 @@ int testapprun(instance_data_t *inst, int message)
                 }
                 case DWT_SIG_TX_AA_DONE: //ignore this event - just process the rx frame that was received before the ACK response
                 case 0:
-                default :
+                default:
                 {
                 	//TODO maybe also check the events to see if nothing is upcoming that will handle this for us!
                 	//check if RX is on every so often. Turn it on if it isn't.
@@ -1367,52 +2002,63 @@ int testapprun(instance_data_t *inst, int message)
 						if(regval == 0){//RX IDLE
 							dwt_forcetrxoff();
 							instancerxon(inst, 0, 0);
-							uint8 debug_msg[200];
-							int n = sprintf((char *)&debug_msg, "RX IDLE, RESET: regval %u", regval);
-							send_usbmessage(&debug_msg[0], n);
-							usb_run();
+//							uint8 debug_msg[200];
+//							int n = sprintf((char *)&debug_msg, "RX IDLE, RESET: regval %u", regval);
+//							send_usbmessage(&debug_msg[0], n);
+//							usb_run();
 						}
 
 
-						uint8 debug_msg[200];
-						int n = sprintf((char *)&debug_msg, "RX CHECKED: regval %u", regval);
-						send_usbmessage(&debug_msg[0], n);
-						usb_run();
+//						uint8 debug_msg[200];
+//						int n = sprintf((char *)&debug_msg, "RX CHECKED: regval %u", regval);
+//						send_usbmessage(&debug_msg[0], n);
+//						usb_run();
 
 					}
 
 
-                    if(inst->mode == ANCHOR)
-                    {   
-//                        send_rxmsgtousb("RX process: default ");
-
-                    	uint32 delta_t = portGetTickCnt() - inst->currentStateStartTime;
-                    	if(delta_t > 20000){
+					//check if it's time to BLINK
+					if(tdma_handler->check_blink(tdma_handler) == TRUE)
+					{
+						inst->testAppState = TA_TX_SELECT;
+					}
 
 
-							 uint8 buffer[SYS_STATUS_LEN];
-							uint64 sys_status_reg;
-							dwt_readfromdevice(SYS_STATUS_ID,0,SYS_STATUS_LEN,buffer);
 
-							for (int j = SYS_STATUS_LEN-1 ; j >= 0 ; j --)
-							{
-								sys_status_reg = (sys_status_reg << 8) + buffer[j] ;
-							}
 
-							uint64 sys_state_reg;
-							dwt_readfromdevice(SYS_STATE_ID,0,SYS_STATE_LEN,buffer);
+//                    if(inst->mode == ANCHOR)
+//                    {
+////                        send_rxmsgtousb("RX process: default ");
+//
+//                    	uint32 delta_t = portGetTickCnt() - inst->currentStateStartTime;
+//                    	if(delta_t > 20000){
+//
+//
+//							 uint8 buffer[SYS_STATUS_LEN];
+//							uint64 sys_status_reg;
+//							dwt_readfromdevice(SYS_STATUS_ID,0,SYS_STATUS_LEN,buffer);
+//
+//							for (int j = SYS_STATUS_LEN-1 ; j >= 0 ; j --)
+//							{
+//								sys_status_reg = (sys_status_reg << 8) + buffer[j] ;
+//							}
+//
+//							uint64 sys_state_reg;
+//							dwt_readfromdevice(SYS_STATE_ID,0,SYS_STATE_LEN,buffer);
+//
+//							for (int j = SYS_STATE_LEN-1 ; j >= 0 ; j --)
+//							{
+//								sys_state_reg = (sys_state_reg << 8) + buffer[j] ;
+//							}
+//
+////							uint8 debug_msg[200];
+////							int n = sprintf((char *)&debug_msg, "SYS_STATUS: %llu SYS_STATE: %llu", sys_status_reg, sys_state_reg);
+////							send_usbmessage(&debug_msg[0], n);
+////							usb_run();
+//                    	}
+//                    }
 
-							for (int j = SYS_STATE_LEN-1 ; j >= 0 ; j --)
-							{
-								sys_state_reg = (sys_state_reg << 8) + buffer[j] ;
-							}
 
-							uint8 debug_msg[200];
-							int n = sprintf((char *)&debug_msg, "SYS_STATUS: %llu SYS_STATE: %llu", sys_status_reg, sys_state_reg);
-							send_usbmessage(&debug_msg[0], n);
-							usb_run();
-                    	}
-                    }
                     if(done == INST_NOT_DONE_YET)
                     {
                         done = INST_DONE_WAIT_FOR_NEXT_EVENT;
@@ -1447,40 +2093,43 @@ int testapprun(instance_data_t *inst, int message)
 // function to initialise instance structures
 //
 // Returns 0 on success and -1 on error
-int instance_init_s(int mode)
+int instance_init_s()
 {
     instance_data_t* inst = instance_get_local_structure_ptr(0);
 
-
-    inst->mode =  mode;                                // assume anchor,
+    inst->mode = DISCOVERY;
     inst->testAppState = TA_INIT;
 
-//    inst->blink_duration = BLINK_DURATION_MS;
-//    inst->range_duration = RANGE_DURATION_MS;
+//    inst->framelength = MIN_FRAMELENGTH;
+//    inst->maxFramelength = MIN_FRAMELENGTH;
+//    while(inst->maxFramelength < UWB_LIST_SIZE + 1)
+//    {
+//    	inst->maxFramelength *= 2;
+//    }
 //
-//	//TODO move and tie to other #define variables
-//	float_t blink_frequency = 0.0001;
+//    inst->slotDuration = 30; //TODO use a #define or something?
+//    inst->slotAssignments = malloc(sizeof(uint16)*inst->maxFramelength);
+//    for(int i = 0; i < inst->maxFramelength; i++)
+//    {
+//    	uint16 blank = 0x0000;
+//    	memcpy(&inst->slotAssignments[i], &blank, 2);
+//    }
+//    for(int i = 0; i < UWB_LIST_SIZE; i++)
+//    {
+//    	inst->uwbFramelengths[i] = 0;
+//    }
 //
+//    //TODO consider using a scheduler class for all of this...
+//    inst->discoveryStartTime = portGetTickCnt();
+
 //	if(inst->mode == ANCHOR){
-//		inst->rx_scheduler = RXScheduler.new(blink_frequency, inst->range_duration, &inst->uwbList, &inst->uwbListLen, UWB_LIST_SIZE, inst->uwbTimeout);
+//		inst->rx_scheduler = RXScheduler.new(BLINK_FREQUENCY, BLINK_DURATION_MS, RANGE_DURATION_MS, &inst->uwbList, &inst->uwbListLen, UWB_LIST_SIZE, inst->uwbTimeout, inst->time_till_next_reported);//TODO do i need & ???
 //	}
 //	else if(inst->mode == TAG){
-//		inst->tx_scheduler = TXScheduler.new(blink_frequency, inst->blink_duration, inst->range_duration, &inst->uwbList, &inst->uwbListLen, UWB_LIST_SIZE, inst->uwbTimeout);
+//		inst->tx_scheduler = TXScheduler.new(BLINK_FREQUENCY, BLINK_DURATION_MS, RANGE_DURATION_MS, &inst->uwbList, &inst->uwbListLen, UWB_LIST_SIZE, inst->uwbTimeout);
 //	}
-
-//    inst->blink_duration = BLINK_DURATION_MS;
-//	inst->range_duration = RANGE_DURATION_MS;
-
-	//TODO move and tie to other #define variables
-	//float_t blink_frequency = 0.0001;
-
-	if(inst->mode == ANCHOR){
-		inst->rx_scheduler = RXScheduler.new(BLINK_FREQUENCY, BLINK_DURATION_MS, RANGE_DURATION_MS, &inst->uwbList, &inst->uwbListLen, UWB_LIST_SIZE, inst->uwbTimeout, inst->time_till_next_reported);//TODO do i need & ???
-	}
-	else if(inst->mode == TAG){
-		inst->tx_scheduler = TXScheduler.new(BLINK_FREQUENCY, BLINK_DURATION_MS, RANGE_DURATION_MS, &inst->uwbList, &inst->uwbListLen, UWB_LIST_SIZE, inst->uwbTimeout);
-	}
-
+//    inst->tdma_handler = TDMAHandler.new(&inst->uwbList, &inst->uwbListLen, &inst->mode);
+//    tdma_handler = TDMAHandler.new(&inst->uwbList, &inst->uwbListLen, &inst->mode);
 
     // if using auto CRC check (DWT_INT_RFCG and DWT_INT_RFCE) are used instead of DWT_INT_RDFR flag
     // other errors which need to be checked (as they disable receiver) are
@@ -1508,6 +2157,11 @@ int instance_init_s(int mode)
     return 0 ;
 }
 
+
+
+
+
+
 extern uint8 dwnsSFDlen[];
 
 // Pre-compute frame lengths, timeouts and delays needed in ranging process.
@@ -1517,7 +2171,7 @@ void instance_init_timings(void)
     instance_data_t* inst = instance_get_local_structure_ptr(0);
     uint32 pre_len;
     int sfd_len;
-    static const int data_len_bytes[FRAME_TYPE_NB] = {
+    static const int data_len_bytes[FRAME_TYPE_NB - 1] = {
         BLINK_FRAME_LEN_BYTES, RNG_INIT_FRAME_LEN_BYTES, POLL_FRAME_LEN_BYTES,
         RESP_FRAME_LEN_BYTES, FINAL_FRAME_LEN_BYTES};
     int i;
@@ -1566,32 +2220,38 @@ void instance_init_timings(void)
         pre_len *= 99359;
     else
         pre_len *= 101763;
+
+    inst->storedPreLen = pre_len; //store to be used later with inf messages and frame_sync
+
     // Second step is data length for all frame types.
-    for (i = 0; i < FRAME_TYPE_NB; i++)
+    for (i = 0; i < FRAME_TYPE_NB - 1; i++)//exclude INF message, since it changes size
     {
-        // Compute the number of symbols for the given length.
-        inst->frameLengths_us[i] = data_len_bytes[i] * 8
-                         + CEIL_DIV(data_len_bytes[i] * 8, 330) * 48;
-        // Convert from symbols to time and add PHY header length.
-        if(inst->configData.dataRate == DWT_BR_110K)
-        {
-            inst->frameLengths_us[i] *= 820513;
-            inst->frameLengths_us[i] += 17230800;
-        }
-        else if (inst->configData.dataRate == DWT_BR_850K)
-        {
-            inst->frameLengths_us[i] *= 102564;
-            inst->frameLengths_us[i] += 2153900;
-        }
-        else
-        {
-            inst->frameLengths_us[i] *= 12821;
-            inst->frameLengths_us[i] += 2153900;
-        }
-        // Last step: add preamble length and convert to microseconds.
-        inst->frameLengths_us[i] += pre_len;
-        inst->frameLengths_us[i] = CEIL_DIV(inst->frameLengths_us[i], 100000);
+    	inst->frameLengths_us[i] = instance_getmessageduration_us(data_len_bytes[i]);
+
+//        // Compute the number of symbols for the given length.
+//        inst->frameLengths_us[i] = data_len_bytes[i] * 8
+//                         + CEIL_DIV(data_len_bytes[i] * 8, 330) * 48;
+//        // Convert from symbols to time and add PHY header length.
+//        if(inst->configData.dataRate == DWT_BR_110K)
+//        {
+//            inst->frameLengths_us[i] *= 820513;
+//            inst->frameLengths_us[i] += 17230800;
+//        }
+//        else if (inst->configData.dataRate == DWT_BR_850K)
+//        {
+//            inst->frameLengths_us[i] *= 102564;
+//            inst->frameLengths_us[i] += 2153900;
+//        }
+//        else
+//        {
+//            inst->frameLengths_us[i] *= 12821;
+//            inst->frameLengths_us[i] += 2153900;
+//        }
+//        // Last step: add preamble length and convert to microseconds.
+//        inst->frameLengths_us[i] += pre_len;
+//        inst->frameLengths_us[i] = CEIL_DIV(inst->frameLengths_us[i], 100000);
     }
+
     // Final frame wait timeout time.
     inst->fwtoTime_sy = US_TO_SY_INT(inst->frameLengths_us[FINAL])
                         + RX_START_UP_SY + margin_sy;
@@ -1629,6 +2289,36 @@ void instance_init_timings(void)
         inst->smartPowerEn = 0;
 }
 
+uint32 instance_getmessageduration_us(int data_length_bytes)
+{
+	instance_data_t* inst = instance_get_local_structure_ptr(0);
+
+	// Compute the number of symbols for the given length.
+	uint32 framelength_us = data_length_bytes * 8
+				 + CEIL_DIV(data_length_bytes * 8, 330) * 48;
+	// Convert from symbols to time and add PHY header length.
+	if(inst->configData.dataRate == DWT_BR_110K)
+	{
+		framelength_us *= 820513;
+		framelength_us += 17230800;
+	}
+	else if (inst->configData.dataRate == DWT_BR_850K)
+	{
+		framelength_us *= 102564;
+		framelength_us += 2153900;
+	}
+	else
+	{
+		framelength_us *= 12821;
+		framelength_us += 2153900;
+	}
+	// Last step: add preamble length and convert to microseconds.
+	framelength_us += inst->storedPreLen;
+	framelength_us = CEIL_DIV(framelength_us, 100000);
+
+	return framelength_us;
+}
+
 uint64 instance_get_addr(void) //get own address
 {
     instance_data_t* inst = instance_get_local_structure_ptr(0);
@@ -1693,6 +2383,14 @@ uint32 get_dt32(uint32 t1, uint32 t2)
     }
 }
 
+//TODO implement a hashing function to reduce chance of collisions
+//https://stackoverflow.com/questions/31710074/how-to-generate-smaller-unique-number-from-larger-11-bytes-unique-number-gene
+//https://en.m.wikipedia.org/wiki/Pearson_hashing
+uint16 address64to16(uint8 *address)
+{
+	return address[0] + (address[1] << 8);
+}
+
 
 #endif
 
diff --git a/src/application/instance.h b/src/application/instance.h
index 08da86a..2d604df 100644
--- a/src/application/instance.h
+++ b/src/application/instance.h
@@ -17,394 +17,12 @@
 extern "C" {
 #endif
 
+
+#include "application_definitions.h"
 #include "port.h"
 #include "deca_types.h"
 #include "deca_device_api.h"
-#include "tx_scheduler.h"
-#include "rx_scheduler.h"
-
-
-
-/******************************************************************************************************************
-********************* NOTES on Decaranging EVK1000 application features/options ***********************************************************
-*******************************************************************************************************************/
-#define DEEP_SLEEP (0) //To enable deep-sleep set this to 1
-//DEEP_SLEEP mode can be used, for example, by a Tag instance to put the DW1000 into low-power deep-sleep mode
-
-#define CORRECT_RANGE_BIAS  (1)     // Compensate for small bias due to uneven accumulator growth at close up high power
-
-
-
-/******************************************************************************************************************
-*******************************************************************************************************************
-*******************************************************************************************************************/
-
-#define NUM_INST            1
-#define SPEED_OF_LIGHT      (299704644.54) //(299702547.0)     // in m/s in air
-#define MASK_40BIT			(0x00FFFFFFFFFF)  // DW1000 counter is 40 bits
-#define MASK_TXDTS			(0x00FFFFFFFE00)  //The TX timestamp will snap to 8 ns resolution - mask lower 9 bits.
-#define SYS_MASK_VAL        (DWT_INT_TFRS | DWT_INT_RFCG | DWT_INT_RXOVRR | DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO)
-#define DELAY_CALIB (0)                     // when set to 1 - the LCD display will show information used for TX/RX delay calibration
-
-#define SET_TXRX_DELAY (0)                  //when set to 1 - the DW1000 RX and TX delays are set to the TX_DELAY and RX_DELAY defines
-#define TX_ANT_DELAY                0
-#define RX_ANT_DELAY                0
-
-#define USING_64BIT_ADDR (1)                  //when set to 0 - the DecaRanging application will use 16-bit addresses
-#define USING_LCD (1)                         //when set to 0 - the DecaRanging application will not use the LCD display
-
-//! callback events
-#define DWT_SIG_RX_NOERR            0
-#define DWT_SIG_TX_DONE             1       // Frame has been sent
-#define DWT_SIG_RX_OKAY             2       // Frame Received with Good CRC
-#define DWT_SIG_RX_ERROR            3       // Frame Received but CRC is wrong
-#define DWT_SIG_RX_TIMEOUT          4       // Timeout on receive has elapsed
-#define DWT_SIG_TX_AA_DONE          6       // ACK frame has been sent (as a result of auto-ACK)
-#define DWT_SIG_RX_BLINK			7		// Received ISO EUI 64 blink message
-#define DWT_SIG_RX_PHR_ERROR        8       // Error found in PHY Header
-#define DWT_SIG_RX_SYNCLOSS         9       // Un-recoverable error in Reed Solomon Decoder
-#define DWT_SIG_RX_SFDTIMEOUT       10      // Saw preamble but got no SFD within configured time
-#define DWT_SIG_RX_PTOTIMEOUT       11      // Got preamble detection timeout (no preamble detected)
-
-#define DWT_SIG_TX_PENDING          12      // TX is pending
-#define DWT_SIG_TX_ERROR            13      // TX failed
-#define DWT_SIG_RX_PENDING          14      // RX has been re-enabled
-#define DWT_SIG_DW_IDLE             15      // DW radio is in IDLE (no TX or RX pending)
-
-#define SIG_RX_UNKNOWN			99		// Received an unknown frame
-
-// Existing frames type in ranging process.
-enum
-{
-    BLINK = 0,
-    RNG_INIT,
-    POLL,
-    RESP,
-    FINAL,
-    FRAME_TYPE_NB
-};
-
-//TWO WAY RANGING function codes
-#define RTLS_DEMO_MSG_RNG_INIT              (0x20)          // Ranging initiation message
-#define RTLS_DEMO_MSG_TAG_POLL              (0x21)          // Tag poll message
-#define RTLS_DEMO_MSG_ANCH_RESP             (0x10)          // Anchor response to poll
-#define RTLS_DEMO_MSG_TAG_FINAL             (0x29)          // Tag final massage back to Anchor (0x29 because of 5 byte timestamps needed for PC app)
-
-//lengths including the Decaranging Message Function Code byte
-#define TAG_POLL_MSG_LEN                    1				// FunctionCode(1),
-#define ANCH_RESPONSE_MSG_LEN               15               // FunctionCode(1), RespOption (1), OptionParam(2), Number of Tags(1), Measured_TOF_Time(6), Time Till next window reserved for catching a blink message (4)
-#define TAG_FINAL_MSG_LEN                   16              // FunctionCode(1), Poll_TxTime(5), Resp_RxTime(5), Final_TxTime(5)
-#define RANGINGINIT_MSG_LEN					7				// FunctionCode(1), Tag Address (2), Response Time (2) * 2
-
-#define MAX_MAC_MSG_DATA_LEN                (TAG_FINAL_MSG_LEN) //max message len of the above
-
-#define STANDARD_FRAME_SIZE         127
-
-#define ADDR_BYTE_SIZE_L            (8)
-#define ADDR_BYTE_SIZE_S            (2)
-
-#define FRAME_CONTROL_BYTES         2
-#define FRAME_SEQ_NUM_BYTES         1
-#define FRAME_PANID                 2
-#define FRAME_CRC					2
-#define FRAME_SOURCE_ADDRESS_S        (ADDR_BYTE_SIZE_S)
-#define FRAME_DEST_ADDRESS_S          (ADDR_BYTE_SIZE_S)
-#define FRAME_SOURCE_ADDRESS_L        (ADDR_BYTE_SIZE_L)
-#define FRAME_DEST_ADDRESS_L          (ADDR_BYTE_SIZE_L)
-#define FRAME_CTRLP					(FRAME_CONTROL_BYTES + FRAME_SEQ_NUM_BYTES + FRAME_PANID) //5
-#define FRAME_CRTL_AND_ADDRESS_L    (FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_L + FRAME_CTRLP) //21 bytes for 64-bit addresses)
-#define FRAME_CRTL_AND_ADDRESS_S    (FRAME_DEST_ADDRESS_S + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //9 bytes for 16-bit addresses)
-#define FRAME_CRTL_AND_ADDRESS_LS	(FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //15 bytes for 1 16-bit address and 1 64-bit address)
-//#define MAX_USER_PAYLOAD_STRING_LL     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 21 - 16 - 2 = 88
-//#define MAX_USER_PAYLOAD_STRING_SS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 9 - 16 - 2 = 100
-//#define MAX_USER_PAYLOAD_STRING_LS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 15 - 16 - 2 = 94
-#define MAX_USER_PAYLOAD_STRING_LL     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-FRAME_CRC) //127 - 21 - 2 = 104
-#define MAX_USER_PAYLOAD_STRING_SS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-FRAME_CRC) //127 - 9 - 2 = 116
-#define MAX_USER_PAYLOAD_STRING_LS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-FRAME_CRC) //127 - 15 - 2 = 110
-
-//NOTE: the user payload assumes that there are only 88 "free" bytes to be used for the user message (it does not scale according to the addressing modes)
-#define MAX_USER_PAYLOAD_STRING	MAX_USER_PAYLOAD_STRING_LL
-
-// Total frame lengths.
-#if (USING_64BIT_ADDR == 1)
-    #define RNG_INIT_FRAME_LEN_BYTES (RANGINGINIT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
-    #define POLL_FRAME_LEN_BYTES (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
-    #define RESP_FRAME_LEN_BYTES (ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
-    #define FINAL_FRAME_LEN_BYTES (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC)
-#else
-    #define RNG_INIT_FRAME_LEN_BYTES (RANGINGINIT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC)
-    #define POLL_FRAME_LEN_BYTES (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
-    #define RESP_FRAME_LEN_BYTES (ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
-    #define FINAL_FRAME_LEN_BYTES (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
-#endif
-
-#define BLINK_FRAME_CONTROL_BYTES       (1)
-#define BLINK_FRAME_SEQ_NUM_BYTES       (1)
-#define BLINK_FRAME_CRC					(FRAME_CRC)
-#define BLINK_FRAME_SOURCE_ADDRESS      (ADDR_BYTE_SIZE_L)
-#define BLINK_FRAME_CTRLP				(BLINK_FRAME_CONTROL_BYTES + BLINK_FRAME_SEQ_NUM_BYTES) //2
-#define BLINK_FRAME_CRTL_AND_ADDRESS    (BLINK_FRAME_SOURCE_ADDRESS + BLINK_FRAME_CTRLP) //10 bytes
-#define BLINK_FRAME_LEN_BYTES           (BLINK_FRAME_CRTL_AND_ADDRESS + BLINK_FRAME_CRC)
-
-#define UWB_LIST_SIZE				    (25)	//maximum number of UWBs to range with (valid options are 0 through 244)
-#define UWB_COMM_TIMEOUT                3000    //ms	//TODO maybe make this a function of other defines?
-
-#define BLINK_SLEEP_DELAY					0     //ms //how long the tag should sleep after blinking
-#define POLL_SLEEP_DELAY					25     //ms //how long the tag should sleep after ranging
-
-
-
-#define IMMEDIATE_RESPONSE (1)
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-// NOTE: the maximum RX timeout is ~ 65ms
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-#define INST_DONE_WAIT_FOR_NEXT_EVENT   1   //this signifies that the current event has been processed and instance is ready for next one
-#define INST_DONE_WAIT_FOR_NEXT_EVENT_TO    2   //this signifies that the current event has been processed and that instance is waiting for next one with a timeout
-                                        //which will trigger if no event coming in specified time
-#define INST_NOT_DONE_YET               0   //this signifies that the instance is still processing the current event
-
-// Function code byte offset (valid for all message types).
-#define FCODE                               0               // Function code is 1st byte of messageData
-// Final message byte offsets.
-#define PTXT                                1
-#define RRXT                                6
-#define FTXT                                11
-
-
-// Anchor response byte offsets.
-#define RES_R1                              1               // Response option octet 0x02 (1),
-#define RES_R2                              2               // Response option parameter 0x00 (1) - used to notify Tag that the report is coming
-#define RES_R3                              3               // Response option parameter 0x00 (1),
-#define NTAG                                4               // Offset to put number of active TAGs in the report message. (1 byte)
-#define TOFR                                5               // Offset to put ToF values in the report message.			  (6 bytes)
-#define TIME_TILL						    11				// Offset to put time until next RX_ACCEPT in the report message (4 bytes)
-
-// Ranging init message byte offsets. Composed of tag short address, anchor
-// response delay and tag response delay.
-#define RNG_INIT_TAG_SHORT_ADDR_LO 1
-#define RNG_INIT_TAG_SHORT_ADDR_HI 2
-#define RNG_INIT_ANC_RESP_DLY_LO 3
-#define RNG_INIT_ANC_RESP_DLY_HI 4
-#define RNG_INIT_TAG_RESP_DLY_LO 5
-#define RNG_INIT_TAG_RESP_DLY_HI 6
-
-// Response delay values coded in ranging init message.
-// This is a bitfield composed of:
-//   - bits 0 to 14: value
-//   - bit 15: unit
-#define RESP_DLY_VAL_SHIFT 0
-#define RESP_DLY_VAL_MASK 0x7FFF
-#define RESP_DLY_UNIT_SHIFT 15
-#define RESP_DLY_UNIT_MASK 0x8000
-
-// Response time possible units: microseconds or milliseconds.
-#define RESP_DLY_UNIT_US 0
-#define RESP_DLY_UNIT_MS 1
-
-// Response delays types present in ranging init message.
-enum
-{
-    RESP_DLY_ANC = 0,
-    RESP_DLY_TAG,
-    RESP_DLY_NB
-};
-
-// Convert microseconds to symbols, float version.
-// param  x  value in microseconds
-// return  value in symbols.
-#define US_TO_SY(x) ((x) / 1.0256)
-
-// Convert microseconds to symbols, integer version.
-// param  x  value in microseconds
-// return  value in symbols.
-// /!\ Due to the the multiplication by 10000, be careful about potential
-// values and type for x to avoid overflows.
-#define US_TO_SY_INT(x) (((x) * 10000) / 10256)
-
-// Minimum delay between reception and following transmission.
-#define RX_TO_TX_TIME_US 300//150 //TODO tune again
-#define RXTOTXTIME          ((int)(150.0 / 1.0256)) //e.g. Poll RX to Response TX time
-
-// Default anchor turn-around time: has to be RX_TO_TX_TIME_US when using
-// immediate response, cannot be less than 170 us when not.
-#define ANC_TURN_AROUND_TIME_US RX_TO_TX_TIME_US
-#if (IMMEDIATE_RESPONSE == 1) && (ANC_TURN_AROUND_TIME_US != RX_TO_TX_TIME_US)
-    #error "When using immediate response, anchor turn-around time has to be equal to RX to TX time!"
-#endif
-// Default tag turn-around time: cannot be less than 300 us. Defined as 500 us
-// so that the tag is not transmitting more than one frame by millisecond (for
-// power management purpose).
-#define TAG_TURN_AROUND_TIME_US 2000//300 //TODO fix again!!!
-
-// "Long" response delays value. Over this limit, special processes must be
-// applied.
-#define LONG_RESP_DLY_LIMIT_US 25000
-
-// Delay between blink reception and ranging init message. This is the same for
-// all modes.
-#define RNG_INIT_REPLY_DLY_MS (20)
-
-#define MAX(a,b) \
-   ({ __typeof__ (a) _a = (a); \
-       __typeof__ (b) _b = (b); \
-     _a > _b ? _a : _b; })
-
-
-#define BLINK_DURATION_MS						RNG_INIT_REPLY_DLY_MS + 1
-#define RANGE_DURATION_MS						MAX(18, POLL_SLEEP_DELAY)  //to increase time between ranging, modify POLL_SLEEP_DELAY
-#define BLINK_FREQUENCY							0.0001
-
-#define RX_CHECK_ON_PERIOD						200; //TODO modify
-
-// Reception start-up time, in symbols.
-#define RX_START_UP_SY 16
-
-typedef uint64_t        uint64 ;
-
-typedef int64_t         int64 ;
-
-
-typedef enum instanceModes{LISTENER, TAG, ANCHOR, TAG_TDOA, NUM_MODES} INST_MODE;
-
-//Listener = in this mode, the instance only receives frames, does not respond
-//Tag = Exchanges DecaRanging messages (Poll-Response-Final) with Anchor and enabling Anchor to calculate the range between the two instances
-//Anchor = see above
-
-typedef enum inst_states
-{
-    TA_INIT,                    //0
-
-    TA_TXE_WAIT,                //1
-    TA_TXPOLL_WAIT_SEND,        //2
-    TA_TXFINAL_WAIT_SEND,       //3
-    TA_TXRESPONSE_WAIT_SEND,    //4
-    TA_TX_WAIT_CONF,            //6
-
-    TA_RXE_WAIT,                //7
-    TA_RX_WAIT_DATA,            //8
-
-    TA_SLEEP_DONE,              //9
-    TA_TXBLINK_WAIT_SEND,       //10
-    TA_TXRANGINGINIT_WAIT_SEND, //11
-    TA_TX_SELECT                //12
-} INST_STATES;
-
-
-// This file defines data and functions for access to Parameters in the Device
-//message structure for Poll, Response and Final message
-
-typedef struct
-{
-    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
-    uint8 seqNum;                               	//  sequence_number 02
-    uint8 panID[2];                             	//  PAN ID 03-04
-    uint8 destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
-    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	//  13-20 using 64 bit addresses
-    uint8 messageData[MAX_USER_PAYLOAD_STRING_LL] ; //  21-124 (application data and any user payload)
-    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
-} srd_msg_dlsl ;
-
-typedef struct
-{
-    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
-    uint8 seqNum;                               	//  sequence_number 02
-    uint8 panID[2];                             	//  PAN ID 03-04
-    uint8 destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
-    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	//  07-08
-    uint8 messageData[MAX_USER_PAYLOAD_STRING_SS] ; //  09-124 (application data and any user payload)
-    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
-} srd_msg_dsss ;
-
-typedef struct
-{
-    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
-    uint8 seqNum;                               	//  sequence_number 02
-    uint8 panID[2];                             	//  PAN ID 03-04
-    uint8 destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
-    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	//  13-14
-    uint8 messageData[MAX_USER_PAYLOAD_STRING_LS] ; //  15-124 (application data and any user payload)
-    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
-} srd_msg_dlss ;
-
-typedef struct
-{
-    uint8 frameCtrl[2];                         	//  frame control bytes 00-01
-    uint8 seqNum;                               	//  sequence_number 02
-    uint8 panID[2];                             	//  PAN ID 03-04
-    uint8 destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
-    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	//  07-14 using 64 bit addresses
-    uint8 messageData[MAX_USER_PAYLOAD_STRING_LS] ; //  15-124 (application data and any user payload)
-    uint8 fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
-} srd_msg_dssl ;
-
-//12 octets for Minimum IEEE ID blink
-typedef struct
-{
-    uint8 frameCtrl;                         		//  frame control bytes 00
-    uint8 seqNum;                               	//  sequence_number 01
-    uint8 tagID[BLINK_FRAME_SOURCE_ADDRESS];        //  02-09 64 bit address
-    uint8 fcs[2] ;                              	//  10-11  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
-} iso_IEEE_EUI64_blink_msg ;
-
-typedef struct
-{
-    uint8 channelNumber ;       // valid range is 1 to 11
-    uint8 preambleCode ;        // 00 = use NS code, 1 to 24 selects code
-    uint8 pulseRepFreq ;        // NOMINAL_4M, NOMINAL_16M, or NOMINAL_64M
-    uint8 dataRate ;            // DATA_RATE_1 (110K), DATA_RATE_2 (850K), DATA_RATE_3 (6M81)
-    uint8 preambleLen ;         // values expected are 64, (128), (256), (512), 1024, (2048), and 4096
-    uint8 pacSize ;
-    uint8 nsSFD ;
-    uint16 sfdTO;  //!< SFD timeout value (in symbols) e.g. preamble length (128) + SFD(8) - PAC + some margin ~ 135us... DWT_SFDTOC_DEF; //default value
-} instanceConfig_t ;
-
-
-/******************************************************************************************************************
-*******************************************************************************************************************
-*******************************************************************************************************************/
-
-#define MAX_EVENT_NUMBER (8)
-//NOTE: Accumulators don't need to be stored as part of the event structure as when reading them only one RX event can happen...
-//the receiver is singly buffered and will stop after a frame is received
-
-typedef struct
-{
-	uint8  type;			// event type
-	uint8  typeSave;		// holds the event type - does not clear (used to show what event has been processed)
-	uint8  typePend;	    // set if there is a pending event (i.e. DW is not in IDLE (TX/RX pending)
-	uint16 rxLength ;
-
-	uint64 timeStamp ;		// last timestamp (Tx or Rx)
-
-	uint32 timeStamp32l ;		   // last tx/rx timestamp - low 32 bits
-	uint32 timeStamp32h ;		   // last tx/rx timestamp - high 32 bits
-
-	union {
-			//holds received frame (after a good RX frame event)
-			uint8   frame[STANDARD_FRAME_SIZE];
-    		srd_msg_dlsl rxmsg_ll ; //64 bit addresses
-			srd_msg_dssl rxmsg_sl ;
-			srd_msg_dlss rxmsg_ls ;
-			srd_msg_dsss rxmsg_ss ; //16 bit addresses
-			iso_IEEE_EUI64_blink_msg rxblinkmsg;
-	}msgu;
-
-}event_data_t ;
-
-#define RTD_MED_SZ          8      // buffer size for mean of 8
-
-typedef struct {
-                uint8 PGdelay;
-
-                //TX POWER
-                //31:24     BOOST_0.125ms_PWR
-                //23:16     BOOST_0.25ms_PWR-TX_SHR_PWR
-                //15:8      BOOST_0.5ms_PWR-TX_PHR_PWR
-                //7:0       DEFAULT_PWR-TX_DATA_PWR
-                uint32 txPwr[2]; //
-}tx_struct;
+#include "tdma_handler.h"
 
 
 typedef struct
@@ -449,14 +67,26 @@ typedef struct
     // Pre-computed frame lengths for frames involved in the ranging process,
     // in microseconds.
     uint32 frameLengths_us[FRAME_TYPE_NB];
+    uint32 storedPreLen;           //precomputed conversion of preamble and sfd
 
 	//message structures used for transmitted messages
 #if (USING_64BIT_ADDR == 1)
 	srd_msg_dlsl rng_initmsg ;	// ranging init message (destination long, source long)
-    srd_msg_dlsl msg[UWB_LIST_SIZE] ; // simple 802.15.4 frame structure (used for tx message) - using long addresses
+//    srd_msg_dlsl msg[UWB_LIST_SIZE] ; // simple 802.15.4 frame structure (used for tx message) - using long addresses
+//    srd_ext_msg_dlsl msg[UWB_LIST_SIZE] ; // simple 802.15.4 frame structure (used for tx message) - using long addresses
+    srd_ext_msg_dlsl msg; // simple 802.15.4 frame structure (used for tx message) - using long addresses
+	srd_ext_msg_dssl inf_msg;         	  // extended inf message containing frame lengths and slot assignments
+    srd_ext_msg_dssl report_msg;          // extended report message containing the calculated range
+//    srd_ext_msg_dlsl ranging_msg; //extended frame structure
 #else
 	srd_msg_dlss rng_initmsg ;  // ranging init message (destination long, source short)
-    srd_msg_dsss msg[UWB_LIST_SIZE] ; // simple 802.15.4 frame structure (used for tx message) - using short addresses
+//    srd_msg_dsss msg[UWB_LIST_SIZE] ; // simple 802.15.4 frame structure (used for tx message) - using short addresses
+//    srd_ext_msg_dsss msg[UWB_LIST_SIZE] ; // simple 802.15.4 frame structure (used for tx message) - using short addresses
+    srd_ext_msg_dsss msg; // simple 802.15.4 frame structure (used for tx message) - using short addresses
+//    srd_ext_msg_dlss rng_initmsg ;  //extended ranging init message (destination long, source short)
+    srd_ext_msg_dsss inf_msg;         	  // extended inf message containing frame lengths and slot assignments
+    srd_ext_msg_dsss report_msg;			// extended report message containing the calculated range
+    //    srd_ext_msg_dsss ranging_msg; //extended frame structure
 #endif
 	iso_IEEE_EUI64_blink_msg blinkmsg ; // frame structure (used for tx blink message)
 
@@ -467,9 +97,6 @@ typedef struct
 	uint16  panID ;					// panid used in the frames
 
     uint8 addrByteSize;             // The bytelength used for addresses. 
-    // uint8 relpyAddress[8] ;         // address of the anchor the tag is ranging with
-
-
 
 	//64 bit timestamps
 	//union of TX timestamps
@@ -524,15 +151,17 @@ typedef struct
 	uint8 uwbToRangeWith;	//it is the index of the uwbList array which contains the address of the UWB we are ranging with
     uint8 uwbListLen ;
 
-	uint8 uwbList[UWB_LIST_SIZE][8];
-	uint8 uwbNumActive[UWB_LIST_SIZE];		//number of TAGs each tracked ANCHOR is actively ranging with.
+	uint8 uwbList[UWB_LIST_SIZE][8];		//index 0 reserved for self, rest for other tracked uwbs
+	uint8 uwbListType[UWB_LIST_SIZE];       //UWB_LIST_SELF, UWB_LIST_NEIGHBOR, UWB_LIST_HIDDEN, UWB_LIST_INACTIVE
+
+	uint8 uwbNumActive[UWB_LIST_SIZE];		//number of TAGs each tracked ANCHOR is actively ranging with. //TODO remove?
 
-    // keep track of when final messages so we can drop uwbs that we havent communicated with in a while
-    uint32 lastCommTimeStamp[UWB_LIST_SIZE] ;
+    // keep track of when final messages so we can drop uwbs that we haven't communicated with in a while
+    uint32 lastCommTimeStamp[UWB_LIST_SIZE];
     uint8 uwbTimeout[UWB_LIST_SIZE] ;
 
-    struct TXScheduler tx_scheduler;	//scheduler used by TAG to decide when to blink and when to range with an ANCHOR (and which ANCHOR)
-    struct RXScheduler rx_scheduler;	//scheduler used by ANCHOR to decide which RX messages to accept and respond to
+    uint32 lastRangeTimeStamp[UWB_LIST_SIZE];
+
     uint8 time_till_next_reported[UWB_LIST_SIZE]; //used to keep track of whether we reported the RX_ACCEPT node. 0 if no, 1 if yes.
 
     uint32 blink_start;
@@ -548,7 +177,9 @@ typedef struct
     uint8 dweventIdxIn;
 	uint8 dweventPeek;
 	uint8 monitor;
-	uint32 timeofTx ;
+	uint32 timeofTx;
+	uint32 timeofRxCallback;
+	uint64 timeofRxCallback_dwtime;
 	uint8 smartPowerEn;
 
 	uint32 currentStateStartTime;
@@ -556,6 +187,9 @@ typedef struct
 
 	uint32 rxCheckOnTime;
 
+	uint32 buildFrameTime;
+
+	uint8 ranging;
 
 } instance_data_t ;
 
@@ -575,6 +209,9 @@ int instaddactivateuwbinlist(instance_data_t *inst, uint8 *uwbAddr);
 int instcheckactiveuwbinlist(instance_data_t *inst, uint8 *uwbAddr);
 int instfindfirstactiveuwbinlist(instance_data_t *inst, uint8 startindex);
 int instfindnumactiveuwbinlist(instance_data_t *inst);
+int instfindnumactiveneighbors(instance_data_t *inst);
+int instfindnumactivehidden(instance_data_t *inst);
+int instgetuwblistindex(instance_data_t *inst, uint8 *uwbAddr, uint8 addrByteSize);
 
 
 void instance_readaccumulatordata(void);
@@ -588,7 +225,8 @@ void setupmacframedata(instance_data_t *inst, int fcode);
 // Call init, then call config, then call run. call close when finished
 // initialise the instance (application) structures and DW1000 device
 int instance_init(void);
-int instance_init_s(int mode);
+int instance_init_s();
+int tdma_init_s();
 
 // configure the instance and DW1000 device
 void instance_config(instanceConfig_t *config) ;  
@@ -600,7 +238,7 @@ int instancesendpacket(uint16 length, uint8 txmode, uint32 dtime);
 
 // called (periodically or from and interrupt) to process any outstanding TX/RX events and to drive the ranging application
 int instance_run(void) ;       // returns indication of status report change
-int testapprun(instance_data_t *inst, int message);
+int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int message);
 
 // calls the DW1000 interrupt handler
 #define instance_process_irq(x) 	dwt_isr()  //call device interrupt handler
@@ -618,6 +256,8 @@ void instancesetreplydelay(int datalength);
 // /!\ This function assumes that there is no user payload in the frame.
 void instance_init_timings(void);
 
+uint32 instance_getmessageduration_us(int data_length_bytes);
+
 // set/get the instance roles e.g. Tag/Anchor/Listener
 int instancegetrole(void) ;
 // get the DW1000 device ID (e.g. 0xDECA0130 for MP)
@@ -635,6 +275,7 @@ uint64 instance_get_uwbaddr(uint8 uwb_index); //get uwb address (8 bytes)
 
 uint64 instancenewrangeancadd(void);
 uint64 instancenewrangetagadd(void);
+int instanceisranging(void);
 int instancenewrange(void);
 int instancesleeping(void);
 int instanceanchorwaiting(void);
@@ -669,14 +310,16 @@ uint16 instancerxantdly(void);
 
 int instance_starttxtest(int framePeriod);
 
-// coid instance_
-
+const char* get_instanceModes_string(enum instanceModes mode);
+const char* get_discovery_modes_string(enum discovery_modes mode);
 
 instance_data_t* instance_get_local_structure_ptr(unsigned int x);
 
 uint32 get_dt32(uint32 t1, uint32 t2);
+uint16 address64to16(uint8 *address);
 
-void send_statetousb(instance_data_t *inst);
+//void send_statetousb(instance_data_t *inst);
+void send_statetousb(instance_data_t *inst, struct TDMAHandler *tdma_handle);
 void send_rxmsgtousb(char *data);
 void send_txmsgtousb(char *data);
 char* get_msg_fcode_string(int fcode);
diff --git a/src/application/instance_common.c b/src/application/instance_common.c
index f12e46a..f3747df 100644
--- a/src/application/instance_common.c
+++ b/src/application/instance_common.c
@@ -18,7 +18,7 @@
 #include "deca_spi.h"
 #include "instance.h"
 
-#include "llist.h"
+//#include "llist.h"
 //#include "uwb_select.h"
 
 #include <inttypes.h>
@@ -36,6 +36,7 @@ extern void send_usbmessage(uint8*, int);
 // -------------------------------------------------------------------------------------------------------------------
 
 static instance_data_t instance_data[NUM_INST] ;
+static struct TDMAHandler tdma_handler;
 
 extern const uint16 rfDelays[2];
 extern const tx_struct txSpectrumConfig[8];
@@ -58,6 +59,32 @@ instance_data_t* instance_get_local_structure_ptr(unsigned int x)
 	return &instance_data[x];
 }
 
+// -------------------------------------------------------------------------------------------------------------------
+// Functions
+// -------------------------------------------------------------------------------------------------------------------
+/* @fn 	  instance_get_local_structure_ptr
+ * @brief function to return the pointer to local instance data structure
+ * */
+struct TDMAHandler* tdma_get_local_structure_ptr()
+{
+
+	return &tdma_handler;
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+// function to initialise tdma structures
+//
+// Returns 0 on success and -1 on error
+int tdma_init_s()
+{
+
+    tdma_handler = TDMAHandler.new();
+
+    return 0 ;
+}
+
+
+
 // -------------------------------------------------------------------------------------------------------------------
 // convert microseconds to device time
 uint64 convertmicrosectodevicetimeu (double microsecu)
@@ -187,18 +214,19 @@ int reportTOF(instance_data_t *inst, uint8 uwb_index)
 //
 // -------------------------------------------------------------------------------------------------------------------
 // return index of UWB
-int instgetuwblistindex(instance_data_t *inst, uint8 *uwbAddr)
+int instgetuwblistindex(instance_data_t *inst, uint8 *uwbAddr, uint8 addrByteSize)
 {
     uint8 blank[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 
+
     //add the new UWB to the list, if not already there and there is space
     for(uint8 i=0; i<UWB_LIST_SIZE; i++)
     {
-        if(memcmp(&inst->uwbList[i][0], &uwbAddr[0], inst->addrByteSize) != 0)
+        if(memcmp(&inst->uwbList[i][0], &uwbAddr[0], addrByteSize) != 0)
         {
-            if(memcmp(&inst->uwbList[i][0], &blank[0], inst->addrByteSize) == 0) //blank entry
+            if(memcmp(&inst->uwbList[i][0], &blank[0], addrByteSize) == 0) //blank entry
             {
-                memcpy(&inst->uwbList[i][0], &uwbAddr[0], inst->addrByteSize) ;
+                memcpy(&inst->uwbList[i][0], &uwbAddr[0], addrByteSize) ;
                 inst->uwbListLen = i + 1 ;
 				inst->uwbTimeout[i] = 1;
 				return i;
@@ -227,7 +255,7 @@ int instaddactivateuwbinlist(instance_data_t *inst, uint8 *uwbAddr)
     uint8 blank[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 
     //add the new UWB to the list, if not already there and there is space
-    for(i=0; i<UWB_LIST_SIZE; i++)
+    for(i=1; i<UWB_LIST_SIZE; i++)//0 reserved for self. timeout status not used for self
     {
         if(memcmp(&inst->uwbList[i][0], &uwbAddr[0], inst->addrByteSize) != 0)
         {
@@ -273,7 +301,7 @@ int instcheckactiveuwbinlist(instance_data_t *inst, uint8 *uwbAddr)
     uint8 blank[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 
     //add the new UWB to the list, if not already there and there is space
-    for(i=0; i<UWB_LIST_SIZE; i++)
+    for(i=1; i<UWB_LIST_SIZE; i++)//0 reserved for self, timeout not used for self
     {
         if(memcmp(&inst->uwbList[i][0], &uwbAddr[0], inst->addrByteSize) == 0)
         {
@@ -332,7 +360,7 @@ int instfindnumactiveuwbinlist(instance_data_t *inst)
 {
     uint8 num = 0;
     
-    for(int i=0; i<inst->uwbListLen; i++)
+    for(int i=1; i<inst->uwbListLen; i++) //0 reserved for self, timeout status not applicable
     {
 		if(!inst->uwbTimeout[i])
 		{
@@ -343,6 +371,47 @@ int instfindnumactiveuwbinlist(instance_data_t *inst)
     return num;
 }
 
+// -------------------------------------------------------------------------------------------------------------------
+//
+// function to find the number of neighbor UWBs in our list that are not in a timeout status
+//
+// -------------------------------------------------------------------------------------------------------------------
+int instfindnumactiveneighbors(instance_data_t *inst)
+{
+    uint8 num = 0;
+
+    for(int i=1; i<inst->uwbListLen; i++)// 0 reserved for self, cant be neighbor
+    {
+		if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR)
+		{
+			num++;
+		}
+    }
+
+    return num;
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// function to find the number of hidden neighbor UWBs in our list that are not in a timeout status
+//
+// -------------------------------------------------------------------------------------------------------------------
+int instfindnumactivehidden(instance_data_t *inst)
+{
+    uint8 num = 0;
+
+    for(int i=1; i<inst->uwbListLen; i++)//0 reserved for self, cannot be hidden
+    {
+		if(inst->uwbListType[i] == UWB_LIST_HIDDEN)
+		{
+			num++;
+		}
+    }
+
+    return num;
+}
+
+
 
 // -------------------------------------------------------------------------------------------------------------------
 #if (NUM_INST != 1)
@@ -360,10 +429,12 @@ void instclearuwbList(void)
 	for(int i=0; i<UWB_LIST_SIZE; i++)
 	{
 		instance_data[instance].lastCommTimeStamp[i] = 0;
+		instance_data[instance].lastRangeTimeStamp[i] = 0;
 		instance_data[instance].uwbTimeout[i] = 0;
 		instance_data[instance].time_till_next_reported[i] = 0;
 		
 		memcpy(&instance_data[instance].uwbList[i][0], &blank[0], 8);
+		instance_data[instance].uwbListType[i] = UWB_LIST_INACTIVE;
 	}
 }
 
@@ -375,6 +446,16 @@ int instancegetrole(void)
     return instance_data[0].mode;
 }
 
+int instanceisranging(void)
+{
+    if(instance_data[0].ranging == 1)
+    {
+        return 1;
+    }
+
+    return 0;
+}
+
 int instancenewrange(void)
 {
     if(instance_data[0].newRange)
@@ -449,10 +530,11 @@ void instanceclearcounts(void)
 int instance_init(void)
 {
     int instance = 0 ;
+
     int result;
     
-    instance_data[instance].mode =  ANCHOR;                                // assume listener,
-
+    instance_data[instance].mode =  DISCOVERY;
+    instance_data[instance].ranging = 0;
     instance_data[instance].goToSleep = 0;
 
     instance_data[instance].tofIndex = 0;
@@ -500,7 +582,7 @@ int instance_init(void)
     instance_data[instance].clockOffset = 0;
     instance_data[instance].monitor = 0;
 
-	dwt_setdblrxbuffmode(1);
+//	dwt_setdblrxbuffmode(1);
     return 0 ;
 }
 
@@ -647,8 +729,9 @@ void instance_config(instanceConfig_t *config)
     instance_data[instance].configData.txPreambLength = config->preambleLen ;
     instance_data[instance].configData.rxPAC = config->pacSize ;
     instance_data[instance].configData.nsSFD = config->nsSFD ;
-    instance_data[instance].configData.phrMode = DWT_PHRMODE_STD ;
-    instance_data[instance].configData.sfdTO = config->sfdTO;
+//    instance_data[instance].configData.phrMode = DWT_PHRMODE_STD ;
+    instance_data[instance].configData.phrMode = DWT_PHRMODE_EXT ;
+        instance_data[instance].configData.sfdTO = config->sfdTO;
 
     //configure the channel parameters
     dwt_configure(&instance_data[instance].configData) ;
@@ -665,15 +748,10 @@ void instance_config(instanceConfig_t *config)
     	//MUST change the SPI to < 3MHz as the dwt_otpread will change to XTAL clock
     	port_set_dw1000_slowrate(); //reduce SPI to < 3MHz
 
-//#if (SET_TXRX_DELAY == 0)
     	dwt_otpread(ANTDLY_ADDRESS, &antennaDelay, 1);
 
     	instance_data[instance].txAntennaDelay = ((antennaDelay >> (16*(config->pulseRepFreq - DWT_PRF_16M))) & 0xFFFF) >> 1;
     	instance_data[instance].rxAntennaDelay = instance_data[instance].txAntennaDelay ;
-//#else
-//		instance_data[instance].txAntennaDelay = (uint16)TX_ANT_DELAY;
-//		instance_data[instance].rxAntennaDelay = (uint16)RX_ANT_DELAY;
-//#endif
 
     	//read any data from the OTP for the TX power
     	dwt_otpread(TXCFG_ADDRESS, otpPower, 12);
@@ -694,8 +772,6 @@ void instance_config(instanceConfig_t *config)
 	instance_data[instance].rxAntennaDelay = (uint16)RX_ANT_DELAY;
 #endif
 
-
-
     // -------------------------------------------------------------------------------------------------------------------
     // set the antenna delay, we assume that the RX is the same as TX.
     dwt_setrxantennadelay(instance_data[instance].txAntennaDelay);
@@ -794,16 +870,64 @@ int instance_get_rxl(void) //get number of late Tx frames
 
 void inst_processtxrxtimeout(instance_data_t *inst)
 {
+
+
 	// send_statetousb(inst);
 
-	// uint8 debug_msg[100];
-	// int n = sprintf((char*)&debug_msg[0], "inst_processrxtimeout(), uwbToRangeWith: %i, uwbListlen: %i", inst->uwbToRangeWith, inst->uwbListLen);
-	// send_usbmessage(&debug_msg[0], n);
-	// usb_run();
+//	 uint8 debug_msg[100];
+//	 int n = sprintf((char*)&debug_msg[0], "inst_processrxtimeout(), uwbToRangeWith: %i, uwbListlen: %i", inst->uwbToRangeWith, inst->uwbListLen);
+//	 send_usbmessage(&debug_msg[0], n);
+//	 usb_run();
 	
-    if(inst->mode == ANCHOR) //we did not receive the final/ACK - wait for next poll
+//	tdma_handler.waitForInf = FALSE;
+//	tdma_handler.waitForRngInit = FALSE;
+
+
+	if(inst->mode == DISCOVERY)
+	{
+		inst->wait4ack = 0;
+		inst->uwbToRangeWith = 255;
+//		uint32 maxFrameDuration = tdma_handler.maxFramelength*tdma_handler.slotDuration;
+
+		if(tdma_handler.discovery_mode == WAIT_RNG_INIT || tdma_handler.discovery_mode == WAIT_INF_INIT)
+		{
+//			tdma_handler.discovery_mode = WAIT_INF_REG;
+			uint32 time_now = portGetTickCnt();
+			tdma_handler.set_discovery_mode(&tdma_handler, WAIT_INF_REG, time_now);
+		}
+
+//		if(inst->previousState == TA_TXBLINK_WAIT_SEND)
+//		{
+//			tdma_handler.waitForRngInit = FALSE;
+//		}
+//		else if(inst->previousState == TA_TXRANGINGINIT_WAIT_SEND)
+//		{
+//			tdma_handler.waitForInf = FALSE;
+//		}
+
+		//TODO should I keep/remove this...?
+		if(tdma_handler.check_blink(&tdma_handler) == TRUE)
+		{
+			inst->testAppState = TA_TX_SELECT;
+		}
+		else
+		{
+			inst->testAppState = TA_RXE_WAIT;
+		}
+//		uint32 maxFrameDuration = tdma_handler.maxFramelength*tdma_handler.slotDuration;
+//		if(portGetTickCnt() - tdma_handler.discoveryStartTime > maxFrameDuration) //TODO handle number wrapping!
+//		{
+//			inst->testAppState = TA_TX_SELECT ;
+//		}
+//		else
+//		{
+//			inst->testAppState = TA_RXE_WAIT;
+//		}
+
+		dwt_setrxtimeout(0);
+	}
+	else if(inst->mode == ANCHOR) //we did not receive the final/ACK - wait for next poll
     {
-    	//TODO should I set uwbToRangeWith == 255???
     	inst->wait4ack = 0;
     	inst->uwbToRangeWith = 255;
 		inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
@@ -828,6 +952,7 @@ void inst_processtxrxtimeout(instance_data_t *inst)
 //		}
     }
 
+    inst->previousState = TA_INIT;
     //timeout - disable the radio (if using SW timeout the rx will not be off)
     dwt_forcetrxoff() ;
 }
@@ -849,11 +974,11 @@ void instance_txcallback(const dwt_cb_data_t *txd)
 	dw_event.rxLength = 0;
 	dw_event.typeSave = dw_event.type = DWT_SIG_TX_DONE ;
 
-	// uint32 dt = portGetTickCnt() - instance_data[instance].timeofTx;
-	// char debug_msg[100];
-	// int n = sprintf((char*)&debug_msg[0], "TX CALLBACK: DWT_SIG_TX_DONE. dt: %lu ", dt);
-	// send_usbmessage((uint8*)&debug_msg[0], n);
-	// usb_run();
+//	 uint32 dt = portGetTickCnt() - instance_data[instance].timeofTx;
+//	 char debug_msg[100];
+//	 int n = sprintf((char*)&debug_msg[0], "TX CALLBACK: DWT_SIG_TX_DONE. dt: %lu ", dt);
+//	 send_usbmessage((uint8*)&debug_msg[0], n);
+//	 usb_run();
 
 	instance_putevent(dw_event);
 
@@ -869,14 +994,16 @@ void instance_rxtimeoutcallback(const dwt_cb_data_t *rxd)
 {
 	event_data_t dw_event;
 
-	int instance = 0;
-	uint32 response_time = portGetTickCnt() - instance_data[instance].range_start;
+//	int instance = 0;
+//	uint32 response_time = portGetTickCnt() - instance_data[instance].range_start;
+
+//	uint8 debug_msg[200];
+//	int n = 0;
+//	n = sprintf((char*)&debug_msg[0], "RX TIMEOUT CALLBACK");// duration: %lu", response_time);
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
 
-	uint8 debug_msg[200];
-	int n = 0;
-	n = sprintf((char*)&debug_msg[0], "RX TIMEOUT CALLBACK duration: %lu", response_time);
-	send_usbmessage(&debug_msg[0], n);
-	usb_run();
 
 	dw_event.typeSave = dw_event.type = DWT_SIG_RX_TIMEOUT;
 	dw_event.rxLength = 0;
@@ -889,11 +1016,11 @@ void instance_rxtimeoutcallback(const dwt_cb_data_t *rxd)
 
 void instance_rxerrorcallback(const dwt_cb_data_t *rxd)
 {
-	uint8 debug_msg[200];
-	int n = 0;
-	n = sprintf((char*)&debug_msg[0], "RX ERROR CALLBACK");
-	send_usbmessage(&debug_msg[0], n);
-	usb_run();
+//	uint8 debug_msg[200];
+//	int n = 0;
+//	n = sprintf((char*)&debug_msg[0], "RX ERROR CALLBACK");
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
 
 
 	int instance = 0;
@@ -905,10 +1032,20 @@ void instance_rxerrorcallback(const dwt_cb_data_t *rxd)
 	}
 
 
+//	tdma_handler.waitForInf = FALSE;
+//	tdma_handler.waitForRngInit = FALSE;
+	if(tdma_handler.discovery_mode == WAIT_RNG_INIT || tdma_handler.discovery_mode == WAIT_INF_INIT)
+	{
+//		tdma_handler.discovery_mode = WAIT_INF_REG;
+		uint32 time_now = portGetTickCnt();
+		tdma_handler.set_discovery_mode(&tdma_handler, WAIT_INF_REG, time_now);
+	}
+
+
 	event_data_t dw_event;
 	//re-enable the receiver
 	//for ranging application rx error frame is same as TO - as we are not going to get the expected frame
-	if(instance_data[instance].mode == TAG)		//TODO I think frame filtering error events are causing this!!! maybe just turn rx back on like the tag!
+	if(instance_data[instance].mode == TAG || instance_data[instance].mode == DISCOVERY)
 	{
 		dw_event.type = DWT_SIG_RX_TIMEOUT;
 		dw_event.typeSave = 0x40 | DWT_SIG_RX_TIMEOUT;
@@ -918,10 +1055,10 @@ void instance_rxerrorcallback(const dwt_cb_data_t *rxd)
 	}
 	else
 	{
-		uint8 debug_msg[100];
-		 int n = sprintf((char*)&debug_msg[0], "instancerxon called from  case instance_rxerrorcallback :");
-		 send_usbmessage(&debug_msg[0], n);
-		 usb_run();
+//		uint8 debug_msg[100];
+//		 int n = sprintf((char*)&debug_msg[0], "instancerxon called from  case instance_rxerrorcallback :");
+//		 send_usbmessage(&debug_msg[0], n);
+//		 usb_run();
 
 		 instance_data[instance].uwbToRangeWith = 255;
 
@@ -930,335 +1067,9 @@ void instance_rxerrorcallback(const dwt_cb_data_t *rxd)
 
 }
 
-//void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
-//{
-//	uint8 debug_msg[200];
-//	int n = 0;
-//
-//	int instance = 0;
-//	uint8 rxTimeStamp[5]  = {0, 0, 0, 0, 0};
-//	uint8 srcAddr_index = 0;
-//    uint8 rxd_event = 0;
-//	uint8 fcode_index  = 0;
-//	event_data_t dw_event;
-//
-//	//if we got a frame with a good CRC - RX OK
-//	rxd_event = DWT_SIG_RX_OKAY;
-//
-//	dw_event.rxLength = rxd->datalength;
-//
-//	//need to process the frame control bytes to figure out what type of frame we have received
-//	switch(rxd->fctrl[0])
-//	{
-//		//blink type frame
-//		case 0xC5:
-//			if(rxd->datalength == 12)
-//			{
-//				rxd_event = DWT_SIG_RX_BLINK;
-//				n = sprintf((char*)&debug_msg[0], "RX CALLBACK: DWT_SIG_RX_BLINK");
-//				send_usbmessage(&debug_msg[0], n);
-//				usb_run();
-//			}
-//			else
-//				rxd_event = SIG_RX_UNKNOWN;
-//
-//			break;
-//
-//		//ACK type frame - not supported in this SW - set as unknown (re-enable RX)
-//		case 0x02:
-//			rxd_event = SIG_RX_UNKNOWN;
-//			break;
-//
-//		//data type frames (with/without ACK request) - assume PIDC is on.
-//		case 0x41:
-//		case 0x61:
-//			//read the frame
-//			if(rxd->datalength > STANDARD_FRAME_SIZE)
-//				rxd_event = SIG_RX_UNKNOWN;
-//
-//
-//			//need to check the destination/source address mode
-//			if((rxd->fctrl[1] & 0xCC) == 0x88) //dest & src short (16 bits)
-//			{
-//				fcode_index = FRAME_CRTL_AND_ADDRESS_S; //function code is in first byte after source address
-//				srcAddr_index = FRAME_CTRLP + ADDR_BYTE_SIZE_S;
-//			}
-//			else if((rxd->fctrl[1] & 0xCC) == 0xCC) //dest & src long (64 bits)
-//			{
-//				fcode_index = FRAME_CRTL_AND_ADDRESS_L; //function code is in first byte after source address
-//				srcAddr_index = FRAME_CTRLP + ADDR_BYTE_SIZE_L;
-//			}
-//			else //using one short/one long
-//			{
-//				fcode_index = FRAME_CRTL_AND_ADDRESS_LS; //function code is in first byte after source address
-//
-//				if(((rxd->fctrl[1] & 0xCC) == 0x8C)) //source short
-//				{
-//					srcAddr_index = FRAME_CTRLP + ADDR_BYTE_SIZE_L;
-//				}
-//				else
-//				{
-//					srcAddr_index = FRAME_CTRLP + ADDR_BYTE_SIZE_S;
-//				}
-//
-//			}
-//
-//			break;
-//
-//		//any other frame types are not supported by this application
-//		default:
-//			rxd_event = SIG_RX_UNKNOWN;
-//			break;
-//	}
-//
-//
-//	//read rx timestamp
-//	if((rxd_event == DWT_SIG_RX_BLINK) || (rxd_event == DWT_SIG_RX_OKAY))
-//	{
-//		dwt_readrxtimestamp(rxTimeStamp) ;
-//		dw_event.timeStamp32l =  (uint32)rxTimeStamp[0] + ((uint32)rxTimeStamp[1] << 8) + ((uint32)rxTimeStamp[2] << 16) + ((uint32)rxTimeStamp[3] << 24);
-//		dw_event.timeStamp = rxTimeStamp[4];
-//		dw_event.timeStamp <<= 32;
-//		dw_event.timeStamp += dw_event.timeStamp32l;
-//		dw_event.timeStamp32h = ((uint32)rxTimeStamp[4] << 24) + (dw_event.timeStamp32l >> 8);
-//
-//		dwt_readrxdata((uint8 *)&dw_event.msgu.frame[0], rxd->datalength, 0);  // Read Data Frame
-//	}
-//
-//	dw_event.typeSave = dw_event.type = rxd_event;
-//
-//	//----------------------------------------------------------------------------------------------
-//	//TWR - here we check if we need to respond to a TWR Poll or Response Messages
-//	//----------------------------------------------------------------------------------------------
-//
-//	//dont process unkown signals or non-blinks that aren't addressed to this UWB
-//	if(rxd_event == DWT_SIG_RX_OKAY)
-//	{
-//		if((dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT ) ||
-//		   (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL ) ||
-//		   (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_ANCH_RESP) ||
-//		   (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_FINAL))
-//		{
-//			uint8 destAddr_index = FRAME_CTRLP;
-//
-//			if(memcmp(&instance_data[instance].eui64[0], &dw_event.msgu.frame[destAddr_index], instance_data[instance].addrByteSize) != 0)
-//			{
-//				// n = sprintf((char*)&debug_msg[0], "RX Message not addressed to me");
-//				// send_usbmessage(&debug_msg[0], n);
-//				// usb_run();
-//				rxd_event = SIG_RX_UNKNOWN;
-//			}
-//		}
-//		else
-//		{
-//			rxd_event = SIG_RX_UNKNOWN;
-//		}
-//	}
-//
-//
-//	//ANCHOR RX
-//	//first check if the address is already tracked.
-//	//if not, add it.
-//	//then get the index for that address
-//
-//	//next check if the ANCHOR is busy with a blink or ranging exchange.
-//	//if BLINK message and busy, add an RX_ACCEPT node to the rx_scheduler
-//	//if not busy with a blink/range exchange, check if we can accept the BLINK or POLL
-//	//if we can accept, set to corresponding index, set to 255
-//
-//
-//	int uwb_index = 255;
-//	if(rxd_event == DWT_SIG_RX_BLINK)
-//	{
-//		uwb_index = instcheckactiveuwbinlist(&instance_data[instance], &dw_event.msgu.rxblinkmsg.tagID[0]);
-//
-//		// n = sprintf((char*)&debug_msg[0], "RX CALLBACK RECEIVED: BLINK <- uwb %d", uwb_index);
-//		// send_usbmessage(&debug_msg[0], n);
-//		// usb_run();
-//	}
-//	else if(rxd_event == DWT_SIG_RX_OKAY)
-//	{
-//
-//		uwb_index = instcheckactiveuwbinlist(&instance_data[instance], &dw_event.msgu.frame[srcAddr_index]);
-//
-//
-//		 n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s <- uwb %d ", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), uwb_index);
-//		 send_usbmessage(&debug_msg[0], n);
-//		 usb_run();
-//
-//	}
-//
-//	// select a uwb to range with if certain messages are received when not currently ranging with another uwb
-//	if (instance_data[instance].uwbToRangeWith == 255 && rxd_event != SIG_RX_UNKNOWN)
-//	{
-//		if(uwb_index == 255) //uwb not yet in list, or timed out
-//		{
-//			if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT && instance_data[instance].mode == TAG)
-//			{
-//				//only process range init from anchors not already in our list, or those that have timed out
-//				if(instaddactivateuwbinlist(&instance_data[instance], &dw_event.msgu.frame[srcAddr_index]))
-//				{
-//					uwb_index = instance_data[instance].uwbToRangeWith;
-//				}
-//				else
-//				{
-//					uwb_index = 255;
-//					instance_data[instance].uwbToRangeWith = 255;
-//				}
-//			}
-//			else if(rxd_event == DWT_SIG_RX_BLINK && instance_data[instance].mode == ANCHOR)
-//			{
-//				//TODO consider adding to anchor list once a RTLS_DEMO_MSG_TAG_POLL has been received...
-//				//only process blinks from tags not already in our list, or those that have timed out
-//				if(instaddactivateuwbinlist(&instance_data[instance], &dw_event.msgu.rxblinkmsg.tagID[0]))
-//				{
-//					uwb_index = instance_data[instance].uwbToRangeWith;
-//				}
-//				else
-//				{
-//					uwb_index = 255;
-//					instance_data[instance].uwbToRangeWith = 255;
-//				}
-//			}
-//		}
-//		else //uwb_index != 255, uwb already in list and not timed out
-//		{
-//			if (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL && instance_data[instance].mode == ANCHOR)
-//			{
-//				instance_data[instance].uwbToRangeWith = uwb_index;
-//			}
-//		}
-//	}
-//
-//	int event_placed = 0;
-//	if(uwb_index != 255 && instance_data[instance].uwbToRangeWith == uwb_index)
-//	{
-//		//update the timestamp for the most recent communication
-//		instance_data[instance].lastCommTimeStamp[uwb_index] = portGetTickCnt();
-//
-//		if(rxd_event == DWT_SIG_RX_OKAY)
-//		{
-//			//process RTLS_DEMO_MSG_TAG_POLL immediately.
-//			if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL)
-//			{
-//				uint16 frameLength = 0;
-//
-//				instance_data[instance].tagPollRxTime = dw_event.timeStamp ; //Poll's Rx time
-//
-//#if (IMMEDIATE_RESPONSE == 0)
-//				instance_data[instance].delayedReplyTime = (instance_data[instance].tagPollRxTime + instance_data[instance].responseReplyDelay) >> 8 ;  // time we should send the response
-//#else
-//				instance_data[instance].delayedReplyTime = 0;
-//#endif
-//
-//#if (USING_64BIT_ADDR == 1)
-//				frameLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;
-//#else
-//				frameLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
-//#endif
-//
-//				memcpy(&instance_data[instance].msg[uwb_index].destAddr[0], &dw_event.msgu.frame[srcAddr_index], instance_data[instance].addrByteSize); //remember who to send the reply to (set destination address)
-//
-//				// Write calculated TOF into response message
-//				memcpy(&(instance_data[instance].msg[uwb_index].messageData[TOFR]), &instance_data[instance].tof[uwb_index], 5);
-//
-//				// TODO include the number of active TAGS that the ANCHOR is ranging with
-//				uint8 num_active = 0;
-//				for(int i = 0; i < instance_data[instance].uwbListLen; i++){
-//					if(!instance_data[instance].uwbTimeout[i]){
-//						num_active++;
-//					}
-//				}
-//				memcpy(&(instance_data[instance].msg[uwb_index].messageData[NTAG]), &num_active, 1);
-//
-//
-//				instance_data[instance].tof[uwb_index] = 0; //clear ToF ..
-//
-//				instance_data[instance].msg[uwb_index].seqNum = instance_data[instance].frameSN++;
-//
-//				//set the delayed rx on time (the final message will be sent after this delay)
-////				dwt_setrxaftertxdelay((uint32)instance_data[instance].txToRxDelayAnc_sy);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
-//				 dwt_setrxaftertxdelay(0);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
-//
-//				//response is expected
-//				instance_data[instance].wait4ack = DWT_RESPONSE_EXPECTED;
-//
-//				dwt_writetxfctrl(frameLength, 0, 1);
-//				dwt_writetxdata(frameLength, (uint8 *)  &instance_data[instance].msg[uwb_index], 0) ;	// write the frame data
-//
-//				//report out which message is being sent!
-//				 send_txmsgtousb(get_msg_fcode_string((int)instance_data[instance].msg[uwb_index].messageData[FCODE]));
-//
-//
-//#if (IMMEDIATE_RESPONSE == 1)
-//				dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);
-//#else
-//				if(instancesendpacket(frameLength, DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED, instance_data[instance].delayedReplyTime))
-//				{
-//					dw_event.typePend = DWT_SIG_TX_ERROR ;
-//					dwt_setrxaftertxdelay(0);
-//					instance_data[instance].wait4ack = 0; //clear the flag as the TX has failed the TRX is off
-//					instance_data[instance].lateTX++;
-//				}
-//				else
-//#endif
-//				{
-//					dw_event.typePend = DWT_SIG_TX_PENDING ; // exit this interrupt and notify the application/instance that TX is in progress.
-//					instance_data[instance].timeofTx = portGetTickCnt();
-//				}
-//			}
-//
-//			instance_putevent(dw_event);
-//			event_placed = 1;
-//
-//#if (DEEP_SLEEP == 1)
-//			if (instance_data[instance].sleepingEabled)
-//			{
-//				instance_data[instance].rxmsgcount++;
-//			}
-//#endif
-//		}
-//		else if (rxd_event == DWT_SIG_RX_BLINK)
-//		{
-//			// n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: BLINK");
-//			// send_usbmessage(&debug_msg[0], n);
-//			// usb_run();
-//
-//			instance_putevent(dw_event);
-//			event_placed = 1;
-//
-//#if (DEEP_SLEEP == 1)
-//			if (instance_data[instance].sleepingEabled)
-//			{
-//				instance_data[instance].rxmsgcount++;
-//			}
-//#endif
-//		}
-//	}
-//
-//	// TODO figure out a better way to do this, I'd like to keep it where it was if possible
-//	// Toggle the Host side Receive Buffer Pointer
-//	dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET, 1);
-//
-//
-//	if(!event_placed)
-//	{
-//		// instance_rxerrorcallback(rxd);
-//
-//		instancerxon(&instance_data[instance], 0, 0); //immediately reenable RX
-//	}
-//}
 
 void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 {
-//	uint8 debug_msg[150];
-//	int n = 0;
-
-
-	uint8 debug_msg[150];
-	int n = sprintf((char*)&debug_msg[0], "RX CALLBACK");
-	send_usbmessage(&debug_msg[0], n);
-	usb_run();
 
 	int instance = 0;
 	uint8 rxTimeStamp[5]  = {0, 0, 0, 0, 0};
@@ -1267,6 +1078,21 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 	uint8 fcode_index  = 0;
 	event_data_t dw_event;
 	
+
+//	int num_neighbors = instfindnumactiveneighbors(&instance_data[instance]);
+//	uint8 debug_msg[150];
+//	int n = sprintf((char*)&debug_msg[0], "RX CALLBACK, mode: %s, num_neighbors %d, discovery_mode %s", get_instanceModes_string(instance_data[instance].mode), num_neighbors, get_discovery_modes_string(tdma_handler.discovery_mode));
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
+//		uint8 debug_msg[150];
+//		int n = sprintf((char*)&debug_msg[0], "RX CALLBACK, %llX, xxx", instance_get_addr());
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
+
+
+	uint32 time_now = portGetTickCnt();
+
 	//if we got a frame with a good CRC - RX OK
 	rxd_event = DWT_SIG_RX_OKAY;
 
@@ -1281,10 +1107,10 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 			{
 				rxd_event = DWT_SIG_RX_BLINK;
 
-//				uint8 debug_msg[150];
-//				int n = sprintf((char*)&debug_msg[0], "RX CALLBACK: DWT_SIG_RX_BLINK");
-//				send_usbmessage(&debug_msg[0], n);
-//				usb_run();
+				uint8 debug_msg[150];
+				int n = sprintf((char*)&debug_msg[0], "RX CALLBACK: DWT_SIG_RX_BLINK");
+				send_usbmessage(&debug_msg[0], n);
+				usb_run();
 			}
 			else
 				rxd_event = SIG_RX_UNKNOWN;
@@ -1300,9 +1126,8 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 		case 0x41:
 		case 0x61:
 			//read the frame
-			if(rxd->datalength > STANDARD_FRAME_SIZE)
+			if(rxd->datalength > EXTENDED_FRAME_SIZE)
 				rxd_event = SIG_RX_UNKNOWN;
-
 			
 			//need to check the destination/source address mode
 			if((rxd->fctrl[1] & 0xCC) == 0x88) //dest & src short (16 bits)
@@ -1357,11 +1182,10 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 	//TWR - here we check if we need to respond to a TWR Poll or Response Messages
 	//----------------------------------------------------------------------------------------------
 
-	//don't process unknown signals or non-blinks that aren't addressed to this UWB
+	//don't process unknown signals or non-broadcast messages that aren't addressed to this UWB
 	if(rxd_event == DWT_SIG_RX_OKAY)
 	{
 
-
 		if((dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT ) || 
 		   (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL ) ||
 		   (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_ANCH_RESP) ||
@@ -1369,24 +1193,41 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 		{
 			uint8 destAddr_index = FRAME_CTRLP;
 
-			//TODO make work with short address
-			if(memcmp(&instance_data[instance].eui64[0], &dw_event.msgu.frame[destAddr_index], instance_data[instance].addrByteSize) != 0)
-			{
-				 n = sprintf((char*)&debug_msg[0], "RX Message not addressed to me");
-				 send_usbmessage(&debug_msg[0], n);
-				 usb_run();
+//#if (USING_64BIT_ADDR==0)
+//			if(memcmp(&instance_data[instance].uwbShortAdd, &dw_event.msgu.frame[destAddr_index], instance_data[instance].addrByteSize) != 0)
+//#else
+//    		if(memcmp(&instance_data[instance].eui64[0], &dw_event.msgu.frame[destAddr_index], instance_data[instance].addrByteSize) != 0)
+//#endif
+			if(memcmp(&instance_data[instance].uwbList[0][0], &dw_event.msgu.frame[destAddr_index], instance_data[instance].addrByteSize) != 0)
+    		{
+//				uint8 debug_msg[150];
+//				int n = sprintf((char*)&debug_msg[0], "RX Message not addressed to me");
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
 				rxd_event = SIG_RX_UNKNOWN;
 			}
 		}
-		else
+
+
+		else if(dw_event.msgu.frame[fcode_index] != RTLS_DEMO_MSG_INF_REG &&
+				dw_event.msgu.frame[fcode_index] != RTLS_DEMO_MSG_INF_INIT &&
+				dw_event.msgu.frame[fcode_index] != RTLS_DEMO_MSG_INF_SUG &&
+				dw_event.msgu.frame[fcode_index] != RTLS_DEMO_MSG_INF_UPDATE &&
+				dw_event.msgu.frame[fcode_index] != RTLS_DEMO_MSG_RNG_REPORT)
 		{
 			rxd_event = SIG_RX_UNKNOWN;
+//			uint8 debug_msg[150];
+//			int n = sprintf((char*)&debug_msg[0], "not INIT/POLL/RESP/FINAL");
+//			 send_usbmessage(&debug_msg[0], n);
+//			 usb_run();
 		}
 	}
 
-//	bool debug = false;
-//	if(rxd_event == DWT_SIG_RX_BLINK){
-//		debug = true;
+//	if(rxd_event == SIG_RX_UNKNOWN){
+//		uint8 debug_msg[150];
+//		int n = sprintf((char*)&debug_msg[0], "RX CALLBACK: SIG_RX_UNKNOWN");
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
 //	}
 
 	//ANCHOR RX
@@ -1396,121 +1237,164 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 	uint8 uwb_index = 255;
 	if(rxd_event == DWT_SIG_RX_BLINK)
 	{
-		uwb_index = instgetuwblistindex(&instance_data[instance], &dw_event.msgu.rxblinkmsg.tagID[0]);
+		uint8 blink_address[8] = {0,0,0,0,0,0,0,0};
+#if (USING_64BIT_ADDR==0)
+		memcpy(&blink_address, &dw_event.msgu.rxblinkmsg.tagID[0], instance_data[instance].addrByteSize);
+#else
+		uint16 blink_address_short = address64to16(&dw_event.msgu.rxblinkmsg.tagID[0]);
+		memcpy(&blink_address, &blink_address_short, instance_data[instance].addrByteSize);
+#endif
 
+		//must be a neighbor
+//		uwb_index = instgetuwblistindex(&instance_data[instance], &dw_event.msgu.rxblinkmsg.tagID[0], instance_data[instance].addrByteSize);
+		uwb_index = instgetuwblistindex(&instance_data[instance], &blink_address[0], instance_data[instance].addrByteSize);
+//		instance_data[instance].uwbListType[uwb_index] = UWB_LIST_NEIGHBOR;
 
-		uint8 debug_msg[100];
-		int n = sprintf((char*)&debug_msg[0], "RX CALLBACK RECEIVED: BLINK uwb_index: %d, uwbToRangeWith: %d ", uwb_index, instance_data[instance].uwbToRangeWith);
-		send_usbmessage(&debug_msg[0], n);
-		usb_run();
+
+//		uint8 debug_msg[100];
+//		int n = sprintf((char*)&debug_msg[0], "RX CALLBACK RECEIVED: BLINK uwb_index: %d, uwbToRangeWith: %d ", uwb_index, instance_data[instance].uwbToRangeWith);
+//		int n = sprintf((char*)&debug_msg[0], "RX CALLBACK RECEIVED: BLINK %llX, xxxx", instance_get_addr());
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
 	}
 	else if(rxd_event == DWT_SIG_RX_OKAY)
 	{
-		uwb_index = instgetuwblistindex(&instance_data[instance], &dw_event.msgu.frame[srcAddr_index]);
-
-		uint8 debug_msg[100];
-		 int n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s uwb_index %d, uwbToRangeWith: %d ", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), uwb_index, instance_data[instance].uwbToRangeWith);
-		 send_usbmessage(&debug_msg[0], n);
-		 usb_run();
-	}
+		//must be a neighbor
+		uwb_index = instgetuwblistindex(&instance_data[instance], &dw_event.msgu.frame[srcAddr_index], instance_data[instance].addrByteSize);
 
+		//TODO maybe do this somewhere else...
+		instance_data[instance].uwbListType[uwb_index] = UWB_LIST_NEIGHBOR;
+		instance_data[instance].lastCommTimeStamp[uwb_index] = time_now;
+		instance_data[instance].uwbTimeout[uwb_index] = 0;
 
-	if(instance_data[instance].mode == ANCHOR)
-	{
-		//TODO this was the missing ingredient, figure out the best way to implement
-		if(instance_data[instance].rx_scheduler.past_accepted_end_Time(&instance_data[instance].rx_scheduler)){
-			instance_data[instance].uwbToRangeWith = 255;
-		}
+//		uint8 debug_msg[100];
+//		 int n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s uwb_index %d, uwbToRangeWith: %d ", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), uwb_index, instance_data[instance].uwbToRangeWith);
+//		 int n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s, %llX, xxxx", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), instance_get_addr());
+//		 send_usbmessage(&debug_msg[0], n);
+//		 usb_run();
 	}
 
-	//next check if the ANCHOR is busy with a blink or ranging exchange.
-	//if BLINK message and busy, add an RX_ACCEPT node to the rx_scheduler
-	//if not busy with a blink/range exchange, check if we can accept the BLINK or POLL
-	//if we can accept, set to corresponding index
+	bool accept_inf = FALSE;
+	//check if the incoming message indicates that we should range with the source UWB or just accept and process the message
 	if(rxd_event != SIG_RX_UNKNOWN)
 	{
-
-		if(instance_data[instance].uwbToRangeWith == 255) //not busy
+		if(instance_data[instance].uwbToRangeWith == 255)
 		{
-			if(instance_data[instance].mode == TAG)
+			if(rxd_event == DWT_SIG_RX_OKAY)
 			{
-				if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT)
+				if(instance_data[instance].mode == ANCHOR)
 				{
-					instance_data[instance].uwbTimeout[uwb_index] = 0;
-					instance_data[instance].lastCommTimeStamp[uwb_index] = portGetTickCnt();
-					instance_data[instance].uwbToRangeWith = uwb_index;
-					instance_data[instance].tx_scheduler.last_select_index = uwb_index;
+					if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL)
+					{
+						//TODO would be good to check if the UWB sending this message was supposed to be ranging in this timeslot
+						instance_data[instance].uwbToRangeWith = uwb_index;
+					}
+					else if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_INF_REG || dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_INF_SUG || dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_INF_UPDATE)//only anchor if already received INF_INIT or collected regular INF messages and joined with SUG message
+					{
+						accept_inf = TRUE;
+					}
 				}
-			}
-			else if(instance_data[instance].mode == ANCHOR)
-			{
-				if((rxd_event == DWT_SIG_RX_BLINK && instance_data[instance].uwbTimeout[uwb_index] == 1) || (dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL))
+				else if (instance_data[instance].mode == DISCOVERY)
 				{
-					RX_MESSAGE_TYPE message_type = RX_POLL;
-					if(rxd_event == DWT_SIG_RX_BLINK)
+					//TODO use switch case?
+					if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT)
 					{
-						message_type = RX_BLINK;
+						if(tdma_handler.discovery_mode == WAIT_RNG_INIT)
+						{
+							//only accept RNG_INIT if no other active neighbors exist (and we are waiting for RNG_INIT)
+							int num_active = instfindnumactiveneighbors(&instance_data[instance]);
+							if(num_active <= 1)
+							{
+								instance_data[instance].uwbToRangeWith = uwb_index;
+							}
+						}
 					}
-
-					if(instance_data[instance].rx_scheduler.rx_accept(&instance_data[instance].rx_scheduler, uwb_index, message_type))
+					else if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_INF_INIT)
 					{
-						instance_data[instance].uwbToRangeWith = uwb_index;
+						//only accept if we are waiting for INF_INIT
+						if(tdma_handler.discovery_mode == WAIT_INF_INIT)
+						{
+							instance_data[instance].uwbToRangeWith = uwb_index;
+							accept_inf = TRUE;
+						}
 					}
-					else if(rxd_event == DWT_SIG_RX_BLINK)
+					else if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_INF_REG ||
+							dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_INF_UPDATE ||
+							dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_INF_SUG)
 					{
-						//add an RX_ACCEPT node to the rx_scheduler
-						rx_timing_node *node = malloc(sizeof(rx_timing_node));
-						node->index = uwb_index;
-						uint32 half_blink_accept_window = 100; //TODO cleanup (should be a function of the max range...)
-						node->duration = half_blink_accept_window*2;
-						node->time = portGetTickCnt() + instance_data[instance].rx_scheduler.blink_period - half_blink_accept_window;
-						node->type = RX_ACCEPT;
-
-						instance_data[instance].rx_scheduler.add_node(&instance_data[instance].rx_scheduler, node);
-
-						uint8 debug_msg[100];
-						int n = sprintf((char *)&debug_msg, "RX_ACCEPT-add_node (uwbToRangeWith == 255), time_now %lu, index %u", portGetTickCnt(), node->index);
-						send_usbmessage(&debug_msg[0], n);
-						usb_run();
+						if(tdma_handler.discovery_mode == WAIT_INF_REG || tdma_handler.discovery_mode == COLLECT_INF_REG)
+						{
+							accept_inf = TRUE;
+						}
 					}
 				}
 			}
-		}
-		else //busy
-		{
-			//note: blinks are auto filtered by DW1000 for TAGs
-			//only process blinks for inactive UWBs
-			if(rxd_event == DWT_SIG_RX_BLINK && instance_data[instance].uwbTimeout[uwb_index] == 1)
+			else if(rxd_event == DWT_SIG_RX_BLINK)
 			{
-				//add an RX_ACCEPT node to the rx_scheduler
-				rx_timing_node *node = malloc(sizeof(rx_timing_node));
-				node->index = uwb_index;
-				uint32 half_blink_accept_window = 100; //TODO cleanup (should be a function of the max range)
-				node->duration = half_blink_accept_window*2;
-				node->time = portGetTickCnt() + instance_data[instance].rx_scheduler.blink_period - half_blink_accept_window;
-				node->type = RX_ACCEPT;
-
-				instance_data[instance].rx_scheduler.add_node(&instance_data[instance].rx_scheduler, node);
-
-				uint8 debug_msg[100];
-				int n = sprintf((char *)&debug_msg, "RX_ACCEPT-add_node, time_now %lu, index %u", portGetTickCnt(), node->index);
-				send_usbmessage(&debug_msg[0], n);
-				usb_run();
+				//only accept BLINK if in DISCOVERY mode and no other active neighbors exist
+				//and not waiting for inf or rng_init
+				if(instance_data[instance].mode == DISCOVERY)
+				{
+					if(tdma_handler.discovery_mode == WAIT_INF_REG)
+					{
+						int num_neighbors = instfindnumactiveneighbors(&instance_data[instance]);
+//						uint8 debug_msg[100];
+//						int n = sprintf((char*)&debug_msg[0], "num_neighbors %d", num_neighbors);
+//						send_usbmessage(&debug_msg[0], n);
+//						usb_run();
+
+						if(num_neighbors <= 1)
+						{
+							instance_data[instance].uwbToRangeWith = uwb_index;
+						}
+					}
+				}
 			}
 		}
 	}
-//	else{
-//		n = sprintf((char*)&debug_msg[0], "SIG_RX_UNKNOWN");
-//		send_usbmessage(&debug_msg[0], n);
-//		usb_run();
-//	}
 
-	n = sprintf((char*)&debug_msg[0], "uwb_index %d, uwbToRangeWith %d", uwb_index, instance_data[instance].uwbToRangeWith);
-	send_usbmessage(&debug_msg[0], n);
-	usb_run();
 
-	int event_placed = 0; 
-	if(uwb_index != 255 && instance_data[instance].uwbToRangeWith == uwb_index)
+//	n = sprintf((char*)&debug_msg[0], "uwb_index %d, uwbToRangeWith %d", uwb_index, instance_data[instance].uwbToRangeWith);
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
+
+	int place_event = 0;
+
+
+	if(rxd_event == DWT_SIG_RX_OKAY && uwb_index != 255)
+	{
+		//always accept.
+		if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_REPORT)
+		{
+//			uint8 debug_msg[100];
+//			 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: RNG_REPORT <- uwb_index %d", uwb_index);
+//			 send_usbmessage(&debug_msg[0], n);
+//			 usb_run();
+			instance_data[instance].lastCommTimeStamp[uwb_index] = time_now;
+			instance_data[instance].uwbTimeout[uwb_index] = 0;
+			place_event = 1;
+		}
+	}
+
+	if(accept_inf == TRUE)
+	{
+		//NOTE: these could get messed up if other messages trigger rxcallback before being processed by frame sync...
+		//should these be folded into the dw_event?
+		//TODO only do this when we need to (we are accepting and INF message)
+		instance_data[instance].timeofRxCallback = time_now;
+
+		//TODO only do this when we need to (we are accepting and INF message)
+		uint8 sys_time_arr[5] = {0, 0, 0, 0, 0};
+		dwt_readsystime(sys_time_arr);
+		instance_data[instance].timeofRxCallback_dwtime = (uint64)sys_time_arr[0] + ((uint64)sys_time_arr[1] << 8) + ((uint64)sys_time_arr[2] << 16) + ((uint64)sys_time_arr[3] << 24) + ((uint64)sys_time_arr[4] << 32);
+
+
+		instance_data[instance].lastCommTimeStamp[uwb_index] = time_now;
+		instance_data[instance].uwbTimeout[uwb_index] = 0;
+		place_event = 1;
+	}
+	else if(uwb_index != 255 && instance_data[instance].uwbToRangeWith == uwb_index)
 	{
 		
 		if(rxd_event == DWT_SIG_RX_OKAY)
@@ -1518,7 +1402,12 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 			//process RTLS_DEMO_MSG_TAG_POLL immediately.
 			if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL)
 			{
-				instance_data[instance].lastCommTimeStamp[uwb_index] = portGetTickCnt();
+//				uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "RX_POLL");
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
+
+				instance_data[instance].lastCommTimeStamp[uwb_index] = time_now;
 				instance_data[instance].uwbTimeout[uwb_index] = 0;
 
 				uint16 frameLength = 0;
@@ -1537,40 +1426,54 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 				frameLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
 #endif
 
-				memcpy(&instance_data[instance].msg[uwb_index].destAddr[0], &dw_event.msgu.frame[srcAddr_index], instance_data[instance].addrByteSize); //remember who to send the reply to (set destination address)
-				
-				//if tof not zero, set tof, else memset 0
-				//also include next TX_ACCEPT node time (offset from now)
-				// Write calculated TOF into response message
-				memcpy(&instance_data[instance].msg[uwb_index].messageData[TOFR], &instance_data[instance].tof[uwb_index], 6); //TODO fix number of bytes...
-
-				uint8 num_active = 0;
-				for(int i = 0; i < instance_data[instance].uwbListLen; i++){
-					if(!instance_data[instance].uwbTimeout[i]){
-						num_active++;
-					}
-				}
-				memcpy(&instance_data[instance].msg[uwb_index].messageData[NTAG], &num_active, 1);
-
-				//get time till the next RX_ACCEPT
-				uint32 time_till = 0;
-				if(instance_data[instance].time_till_next_reported[uwb_index] == 0){
-					time_till =	instance_data[instance].rx_scheduler.get_time_till_next_rx_accept(&instance_data[instance].rx_scheduler);
-					instance_data[instance].time_till_next_reported[uwb_index] = 1;
-				}
-				memcpy(&instance_data[instance].msg[uwb_index].messageData[TIME_TILL], &time_till, 4);
-
+//				instance_data[instance].msg[uwb_index].messageData[FCODE] = RTLS_DEMO_MSG_ANCH_RESP; //message function code (specifies if message is a poll, response or other...)
+//				//program option octet and parameters (not used currently)
+//				instance_data[instance].msg[uwb_index].messageData[RES_R1] = 0x2; // "activity"
+//				instance_data[instance].msg[uwb_index].messageData[RES_R2] = 0x0; //
+//				instance_data[instance].msg[uwb_index].messageData[RES_R3] = 0x0;
+//
+//
+//				memcpy(&instance_data[instance].msg[uwb_index].destAddr[0], &dw_event.msgu.frame[srcAddr_index], instance_data[instance].addrByteSize); //remember who to send the reply to (set destination address)
+//
+//				//if tof not zero, set tof, else memset 0
+//				//also include next TX_ACCEPT node time (offset from now)
+//				// Write calculated TOF into response message
+//				memcpy(&instance_data[instance].msg[uwb_index].messageData[TOFR], &instance_data[instance].tof[uwb_index], 6); //TODO fix number of bytes...
+//
+//				uint8 num_active = 0;
+//				for(int i = 0; i < instance_data[instance].uwbListLen; i++){
+//					if(!instance_data[instance].uwbTimeout[i]){
+//						num_active++;
+//					}
+//				}
+//				memcpy(&instance_data[instance].msg[uwb_index].messageData[NTAG], &num_active, 1);
+//
+//				//get time till the next RX_ACCEPT
+////				uint32 time_till = 0;
+////				if(instance_data[instance].time_till_next_reported[uwb_index] == 0){
+////					time_till =	instance_data[instance].rx_scheduler.get_time_till_next_rx_accept(&instance_data[instance].rx_scheduler);
+////					instance_data[instance].time_till_next_reported[uwb_index] = 1;
+////				}
+////				memcpy(&instance_data[instance].msg[uwb_index].messageData[TIME_TILL], &time_till, 4);
+//
+//
+////				uint8 debug_msg[100];
+////				uint64 mtof = instance_data[instance].msg[uwb_index].messageData[TOFR];
+////				int n = sprintf((char *)&debug_msg, "TOF in resp %llu", mtof);
+////				send_usbmessage(&debug_msg[0], n);
+////				usb_run();
+//
+//
+////				instance_data[instance].tof[uwb_index] = 0; //clear ToF ..
+////
+//				instance_data[instance].msg[uwb_index].seqNum = instance_data[instance].frameSN++;
 
-//				uint8 debug_msg[100];
-//				uint64 mtof = instance_data[instance].msg[uwb_index].messageData[TOFR];
-//				int n = sprintf((char *)&debug_msg, "TOF in resp %llu", mtof);
-//				send_usbmessage(&debug_msg[0], n);
-//				usb_run();
+				instance_data[instance].msg.messageData[FCODE] = RTLS_DEMO_MSG_ANCH_RESP; //message function code (specifies if message is a poll, response or other...)
 
+				memcpy(&instance_data[instance].msg.destAddr[0], &dw_event.msgu.frame[srcAddr_index], instance_data[instance].addrByteSize); //remember who to send the reply to (set destination address)
+				
+				instance_data[instance].msg.seqNum = instance_data[instance].frameSN++;
 
-//				instance_data[instance].tof[uwb_index] = 0; //clear ToF ..
-//
-				instance_data[instance].msg[uwb_index].seqNum = instance_data[instance].frameSN++;
 
 				//set the delayed rx on time (the final message will be sent after this delay)
 //				dwt_setrxaftertxdelay((uint32)instance_data[instance].txToRxDelayAnc_sy);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
@@ -1580,7 +1483,8 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 				instance_data[instance].wait4ack = DWT_RESPONSE_EXPECTED;
 
 				dwt_writetxfctrl(frameLength, 0, 1);
-				dwt_writetxdata(frameLength, (uint8 *)  &instance_data[instance].msg[uwb_index], 0) ;	// write the frame data
+//				dwt_writetxdata(frameLength, (uint8 *)  &instance_data[instance].msg[uwb_index], 0) ;	// write the frame data
+				dwt_writetxdata(frameLength, (uint8 *)  &instance_data[instance].msg, 0) ;	// write the frame data
 
 #if (IMMEDIATE_RESPONSE == 1)
 				dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);
@@ -1596,7 +1500,7 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 #endif
 				{
 					dw_event.typePend = DWT_SIG_TX_PENDING ; // exit this interrupt and notify the application/instance that TX is in progress.
-					instance_data[instance].timeofTx = portGetTickCnt();
+					instance_data[instance].timeofTx = time_now;
 				}
 				//report out which message is being sent!
 //				send_txmsgtousb(get_msg_fcode_string((int)instance_data[instance].msg[uwb_index].messageData[FCODE]));
@@ -1623,73 +1527,67 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 				instance_data[instance].tof[uwb_index] = 0; //clear ToF ..
 
 
-				uint8 debug_msg[100];
-				 int n = sprintf((char*)&debug_msg[0], "RX TAG_POLL ACCEPTED ANCH_RESP sent <- uwb %d", uwb_index);
-				 send_usbmessage(&debug_msg[0], n);
-				 usb_run();
+//				uint8 debug_msg[100];
+//				 n = sprintf((char*)&debug_msg[0], "RX TAG_POLL ACCEPTED ANCH_RESP sent <- uwb %d", uwb_index);
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
 			}
 			else if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_ANCH_RESP)
 			{
 //				uint32 response_time = portGetTickCnt() - instance_data[instance].range_start;
-				instance_data[instance].lastCommTimeStamp[uwb_index] = portGetTickCnt();
+				instance_data[instance].lastCommTimeStamp[uwb_index] = time_now;
 				instance_data[instance].uwbTimeout[uwb_index] = 0;
-				uint8 debug_msg[100];
-				 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: ANCH_RESP <- uwb_index %d", uwb_index);
-				 send_usbmessage(&debug_msg[0], n);
-				 usb_run();
+//				uint8 debug_msg[100];
+//				 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: ANCH_RESP <- uwb_index %d", uwb_index);
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
 			}
 			else if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT)
 			{
-				instance_data[instance].lastCommTimeStamp[uwb_index] = portGetTickCnt();
+				instance_data[instance].lastCommTimeStamp[uwb_index] = time_now;
 				instance_data[instance].uwbTimeout[uwb_index] = 0;
-				uint8 debug_msg[100];
-				 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: RNG_INIT <- uwb_index %d", uwb_index);
-				 send_usbmessage(&debug_msg[0], n);
-				 usb_run();
+//				uint8 debug_msg[100];
+//				 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: RNG_INIT <- uwb_index %d", uwb_index);
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
 			}
 			else if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_FINAL)
 			{
-				instance_data[instance].lastCommTimeStamp[uwb_index] = portGetTickCnt();
+				instance_data[instance].lastCommTimeStamp[uwb_index] = time_now;
 				instance_data[instance].uwbTimeout[uwb_index] = 0;
-				uint8 debug_msg[100];
-				 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: TAG_FINAL <- uwb_index %d", uwb_index);
-				 send_usbmessage(&debug_msg[0], n);
-				 usb_run();
+//				uint8 debug_msg[100];
+//				 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: TAG_FINAL <- uwb_index %d", uwb_index);
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
 			}
-			
-			instance_putevent(dw_event);
-			event_placed = 1;
+//			else if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_REPORT)
+//			{
+//				instance_data[instance].lastCommTimeStamp[uwb_index] = portGetTickCnt();
+//				instance_data[instance].uwbTimeout[uwb_index] = 0;
+//				uint8 debug_msg[100];
+//				 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: RNG_REPORT <- uwb_index %d", uwb_index);
+//				 send_usbmessage(&debug_msg[0], n);
+//				 usb_run();
+//			}
 
-#if (DEEP_SLEEP == 1)
-			if (instance_data[instance].sleepingEabled)
-			{
-				instance_data[instance].rxmsgcount++;
-			}
-#endif
+
+			place_event = 1;
 		}
 		else if (rxd_event == DWT_SIG_RX_BLINK)
 		{
-			uint8 debug_msg[100];
-			 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: BLINK <- uwb %d", uwb_index);
-			 send_usbmessage(&debug_msg[0], n);
-			 usb_run();
-			
-			instance_putevent(dw_event);
-			event_placed = 1;
+//			uint8 debug_msg[100];
+//			 int n = sprintf((char*)&debug_msg[0], "RX CALLBACK ACCEPTED: BLINK <- uwb %d", uwb_index);
+//			 send_usbmessage(&debug_msg[0], n);
+//			 usb_run();
 			
-#if (DEEP_SLEEP == 1)
-			if (instance_data[instance].sleepingEabled)
-			{
-				instance_data[instance].rxmsgcount++;
-			}
-#endif
+			place_event = 1;
 		}
 	}
 
 	// TODO figure out a better way to do this, I'd like to keep it where it was if possible
 	// doing it here because it needs to be toggled before toggling the rx buffer pointer
 	// Toggle the Host side Receive Buffer Pointer
-	dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET, 1);
+//	dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET, 1);
         
 //	uint8 buff = dwt_read8bitoffsetreg(SYS_STATUS_ID, 3);
 //	uint8 debug_msg[100];
@@ -1697,20 +1595,34 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd)
 //	 send_usbmessage(&debug_msg[0], n);
 //	 usb_run();
 
+	if(place_event)
+	{
+		instance_putevent(dw_event);
 
-	if(!event_placed)
+#if (DEEP_SLEEP == 1)
+		if (instance_data[instance].sleepingEabled)
+		{
+			instance_data[instance].rxmsgcount++;
+		}
+#endif
+	}
+	else
 	{
 		// instance_rxerrorcallback(rxd);
 		
-		uint8 debug_msg[100];
-		 int n = sprintf((char*)&debug_msg[0], "instancerxon called from !event_placed :");
-		 send_usbmessage(&debug_msg[0], n);
-		 usb_run();
+//		uint8 debug_msg[100];
+//		 int n = sprintf((char*)&debug_msg[0], "instancerxon called from !event_placed :");
+//		 send_usbmessage(&debug_msg[0], n);
+//		 usb_run();
 
 		instancerxon(&instance_data[instance], 0, 0); //immediately reenable RX
 	}
 }
 
+
+
+
+
 int instance_peekevent(void)
 {
 	int instance = 0;
@@ -1801,32 +1713,67 @@ int instance_run(void)
 
 	while(done == INST_NOT_DONE_YET)
 	{
-		//int state = instance_data[instance].testAppState;
-		done = testapprun(&instance_data[instance], message) ; // run the communications application
+		done = testapprun(&instance_data[instance], &tdma_handler, message) ; // run the communications application
 
 		//we've processed message
 		message = 0;
 	}
 
 	//check if lastCommTimeStamp has expired for any of the uwbs in our list
-	for(int i=0; i < instance_data[instance].uwbListLen; i++)
+	for(int i=1; i < instance_data[instance].uwbListLen; i++)//0 reserved for self, timeout not applicable
 	{
-		if(instance_data[instance].lastCommTimeStamp[i] + UWB_COMM_TIMEOUT < portGetTickCnt())
+		//TODO could also have a timer to put into DISCOVERY if we haven't spoken to anyone in a while
+
+		if(instance_data[instance].lastCommTimeStamp[i] + UWB_COMM_TIMEOUT < portGetTickCnt()) //TODO handle number wrapping
 		{
-			if(instance_data[instance].uwbTimeout[i] == 0)
+//			if(instance_data[instance].uwbTimeout[i] == 0)
+			if(instance_data[instance].uwbListType[i] == UWB_LIST_NEIGHBOR) //what about hidden?
 			{
+				instance_data[instance].uwbListType[i] = UWB_LIST_INACTIVE; //TODO release TDMA slots as well
 				instance_data[instance].uwbTimeout[i] = 1;
 				
+
+
+				//NEW
+				//if no more active neighbors exist, transition to DISCOVERY
+				uint8 numNeighbors = instfindnumactiveneighbors(&instance_data[instance]);
+				if(numNeighbors <= 0)
+				{
+					tdma_handler.tdma_free_all_slots(&tdma_handler);
+
+
+
+//					uint8 debug_msg[100];
+//					int n = sprintf((char *)&debug_msg, "inst_processtxrxtimeout(inst) after free_all_slots");
+//					send_usbmessage(&debug_msg[0], n);
+//					usb_run();
+
+					instance_data[instance].mode = DISCOVERY;						//TODO clear the TDMA slot information!
+					tdma_handler.discoveryStartTime = portGetTickCnt();
+					tdma_handler.enter_discovery_mode(&tdma_handler);
+					inst_processtxrxtimeout(&instance_data[instance]);
+
+					instance_data[instance].canPrintInfo = 0;
+					instance_data[instance].ranging = 0;
+				}
+				else
+				{
+					//TODO check if able to reconfigure tdma assignements. shrink frame size, reassign emptied slots, etc
+					tdma_handler.uwblist_free_slots(&tdma_handler, i);
+				}
+
+
 //				 uint8 debug_msg[100];
 //				 int n = sprintf((char*)&debug_msg[0], "TIMEOUT: uwb %i", i);
 //				 send_usbmessage(&debug_msg[0], n);
 //				 usb_run();
 			}
+
 			if(instance_data[instance].uwbToRangeWith == i)
 			{	
 				instance_data[instance].uwbToRangeWith = 255;	
 				//NOTE this might need to be changed for TAG operations
-				if(instance_data[instance].mode == ANCHOR)
+				if(instance_data[instance].mode == ANCHOR || instance_data[instance].mode == DISCOVERY) //TODO maybe send to TA_MODE_SELECT?
 				{
 					instance_data[instance].testAppState = TA_RXE_WAIT;
 				}
@@ -1843,23 +1790,21 @@ int instance_run(void)
 		
 	}
 
-	
-
-
     if(done == INST_DONE_WAIT_FOR_NEXT_EVENT_TO) //we are in RX and need to timeout (Tag needs to send another poll if no Rx frame)
     {
-        if(instance_data[instance].mode == TAG) //Tag (is either in RX or sleeping)
-        {
-			if(instance_data[instance].previousState == TA_TXBLINK_WAIT_SEND)
+    	if(instance_data[instance].mode == DISCOVERY)
+    	{
+    		if(instance_data[instance].previousState == TA_TXBLINK_WAIT_SEND)
 			{
 				instance_data[instance].instanceTimerTime += instance_data[instance].tagBlinkSleepTime_ms; //set timeout time
-            	instance_data[instance].instanceTimerEnabled = 1; //start timer
-			}
-			else
-			{
-				instance_data[instance].instanceTimerTime = instance_data[instance].instanceTimerTimeSaved + instance_data[instance].tagSleepTime_ms; //set timeout time
-            	instance_data[instance].instanceTimerEnabled = 1; //start timer
+				instance_data[instance].instanceTimerEnabled = 1; //start timer
 			}
+    	}
+
+        if(instance_data[instance].mode == TAG) //Tag (is either in RX or sleeping)
+        {
+			instance_data[instance].instanceTimerTime = instance_data[instance].instanceTimerTimeSaved + instance_data[instance].tagSleepTime_ms; //set timeout time
+			instance_data[instance].instanceTimerEnabled = 1; //start timer
         }
     }
 
@@ -1868,11 +1813,11 @@ int instance_run(void)
     {
         if(instance_data[instance].instanceTimerTime < portGetTickCnt())
         {
-        	uint8 debug_msg[200];
-			int n = 0;
-			n = sprintf((char*)&debug_msg[0], "instance timer expired");
-			send_usbmessage(&debug_msg[0], n);
-			usb_run();
+//        	uint8 debug_msg[200];
+//			int n = 0;
+//			n = sprintf((char*)&debug_msg[0], "instance timer expired");
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
 
 			event_data_t dw_event;
             instance_data[instance].instanceTimerEnabled = 0;
diff --git a/src/application/rx_scheduler.c b/src/application/rx_scheduler.c
index a997630..8c347ee 100644
--- a/src/application/rx_scheduler.c
+++ b/src/application/rx_scheduler.c
@@ -63,7 +63,7 @@ static bool rx_accept(struct RXScheduler *this, uint8 index, RX_MESSAGE_TYPE mes
 	uint8 debug_msg[500];
 	int n = 0;
 	int n_char = 0;
-	bool debug = true;
+	bool debug = false;
 	if(debug){
 		n = sprintf((char*)&debug_msg[0], "rx_accept, time_now %lu, index %u \n", time_now, index);
 		n_char = n;
diff --git a/src/application/tdma_handler.c b/src/application/tdma_handler.c
new file mode 100644
index 0000000..152e47b
--- /dev/null
+++ b/src/application/tdma_handler.c
@@ -0,0 +1,2566 @@
+#include "tdma_handler.h"
+#include "port.h"
+#include "instance.h"
+
+
+extern void usb_run(void);
+extern void send_usbmessage(uint8*, int);
+
+//class methods
+static bool slot_transition(struct TDMAHandler *this)
+{
+	bool transition = FALSE;
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+
+	if(inst->mode == TAG || inst->mode == ANCHOR || (inst->mode == DISCOVERY && this->discovery_mode == WAIT_SEND_SUG))
+	{
+		uint32 time_now = portGetTickCnt();
+
+		uint32 timeSinceSlotStart = get_dt32(this->lastSlotStartTime, time_now);
+		if(timeSinceSlotStart > this->slotDuration)
+		{
+			transition = TRUE;
+			this->infPollSentThisSlot = FALSE;
+
+			//we have transitioned into the next slot.
+			//get the slot number and set the start time appropriately
+			uint32 timeSinceFrameStart = get_dt32(this->uwbFrameStartTimes[0], time_now);
+			if(timeSinceFrameStart > this->slotDuration*this->uwbListTDMAInfo[0].framelength)
+			{
+				uint8 debug_msg[100];
+//				 int n = sprintf((char*)&debug_msg[0], "NEW FRAME, %llX,  this->frameStartTime: %lu, this->slotDuration*this->framelength: %lu", instance_get_addr(), this->frameStartTime, (this->slotDuration*this->framelength));
+				int n = sprintf((char*)&debug_msg[0], "NEW FRAME, %llX, xxxx", instance_get_addr());
+				send_usbmessage(&debug_msg[0], n);
+				usb_run();
+
+				struct TDMAInfo *info = &this->uwbListTDMAInfo[0];
+				bool assigned0 = this->slot_assigned(info, 0);
+				bool assigned1 = this->slot_assigned(info, 1);
+				bool assigned2 = this->slot_assigned(info, 2);
+				bool assigned3 = this->slot_assigned(info, 3);
+
+				n = sprintf((char*)&debug_msg[0], "ass0: %u ass1: %u ass2: %u ass3: %u,", assigned0, assigned1, assigned2, assigned3);
+				send_usbmessage(&debug_msg[0], n);
+				usb_run();
+			}
+
+			while(timeSinceFrameStart > this->slotDuration*this->uwbListTDMAInfo[0].framelength)
+			{
+				this->uwbFrameStartTimes[0] += this->slotDuration*this->uwbListTDMAInfo[0].framelength;
+				timeSinceFrameStart -= this->slotDuration*this->uwbListTDMAInfo[0].framelength;
+			}
+
+			uint8 slot = timeSinceFrameStart/this->slotDuration; //integer division rounded down
+			this->lastSlotStartTime = this->uwbFrameStartTimes[0] + this->slotDuration*(uint32)slot;
+
+
+			uint8 debug_msg[100];
+			int n = sprintf((char*)&debug_msg[0], "NEW SLOT %u, time_now %lu", slot, time_now);
+			 send_usbmessage(&debug_msg[0], n);
+			 usb_run();
+
+
+//			n = sprintf((char*)&debug_msg[0], "&this->slotAssignments[slot]: %u, &inst->uwbShortAdd %u :", this->slotAssignments[slot], inst->uwbShortAdd);
+//			 send_usbmessage(&debug_msg[0], n);
+//			 usb_run();
+
+//			if(this->slot_assigned(this, slot) == TRUE)
+//			{
+//
+//			}
+
+//			struct TDMAInfo *info = &this->uwbListTDMAInfo[0];
+//			bool assigned0 = this->slot_assigned(info, 0);
+//			bool assigned1 = this->slot_assigned(info, 1);
+//			bool assigned2 = this->slot_assigned(info, 2);
+//			bool assigned3 = this->slot_assigned(info, 3);
+//
+//			uint8 debug_msg[100];
+//			int n = sprintf((char*)&debug_msg[0], "NEW SLOT %u, ass0: %u, ass1: %u, ass2: %u, ass3: %u,", slot, assigned0, assigned1, assigned2, assigned3);
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
+
+
+//			if(memcmp(&this->slotAssignments[slot], 	&inst->uwbShortAdd, 2) == 0)
+			if(inst->mode == DISCOVERY)
+			{
+				if(slot == 0)
+				{
+					inst->testAppState = TA_TX_SELECT;
+				}
+			}
+			else
+			{
+				if(this->slot_assigned(&this->uwbListTDMAInfo[0], slot) == TRUE) //TODO left off here, for some reason it fails when I try this...
+				{
+
+					inst->mode = TAG;
+					inst->testAppState = TA_TX_SELECT;
+					//go to TX select, select the oldest uwb, send INF, then send POLL
+				}
+				else
+				{
+					//go to RX
+					inst->mode = ANCHOR;
+					inst->testAppState = TA_RXE_WAIT;
+				}
+			}
+
+//			uint8 debug_msg[100];
+//			n = sprintf((char *)&debug_msg, "inst_processtxrxtimeout(inst) after slot transition");
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
+			instance_getevent(17); //get and clear this event
+			inst_processtxrxtimeout(inst);
+		}
+	}
+	else if(inst->mode == DISCOVERY)
+	{
+		this->infPollSentThisSlot = FALSE;
+	}
+
+	return transition;
+}
+
+//TODO pass in dw_event..
+//static void frame_sync(struct TDMAHandler *this, uint8 *messageData, uint16 rxLength, uint8 srcIndex, FRAME_SYNC_MODE mode)
+static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 *messageData, uint8 srcIndex, FRAME_SYNC_MODE mode)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+
+	uint32 time_now = portGetTickCnt();
+	uint8 framelength;
+	uint32 timeSinceFrameStart;
+
+	memcpy(&framelength, &messageData[TDMA_FRAMELENGTH], 1);
+	//timeSinceFrameStart in message
+	memcpy(&timeSinceFrameStart, &messageData[TDMA_TSFS], sizeof(timeSinceFrameStart));
+
+//	uint8 debug_msg[100];
+//	int n = sprintf((char*)&debug_msg[0], "tsfs %lu :", timeSinceFrameStart);
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
+
+	//account for the delay between transmission and reception of the INF message
+	//TODO make this a function of the data rate as well!
+	//TODO experimentally found this number to be +- 1 millisecond for some reason. figure out why
+	//experimentally found formula is 0.079667x + 0.85611
+//	uint32 txrx_delay = (uint32)(0.079667*(float)(dw_event->rxLength) + 0.85611); //TODO make this function of xmission frequency!
+
+	//time from message to tx
+	//assuming zero since we use DWT_START_TX_IMMEDIATE
+	//if this is a problem then include the sys_time in the messsage. then the tx_timestamp can be used to figure out this delay
+	//NOTE: if this is done, the timestamp in DWT_START_TX_IMMEDIATE includes the antenna delay, so don't do the next step
+
+	//tx antenna delay
+	//NOTE: this is stored in inst->txAntennaDelay;
+	uint32 tx_antenna_delay = convertdevicetimetosec(inst->txAntennaDelay)*1000;
+
+
+	//time for xmission (only count once, happens on both sides near simultaneously)
+	//TODO make sure this is correct...
+	//easiest way to check would be to see if it is the same as the defines for other standard messages...
+	inst->frameLengths_us[INF] = instance_getmessageduration_us(dw_event->rxLength);
+
+
+	//time to propogate
+	//NOTE: assuming zero since difference for speed of light travel time over 10cm and 100m is negligible for frame sync purposes
+
+	//rx antenna delay
+	//NOTE: this is stored in inst->rxAntennaDelay
+	//NOTE: we won't use this, becaues the antenna delay is captured by the RX timestamp
+
+	//time from rx to system process rx
+	uint64 delta_t = inst->timeofRxCallback_dwtime - dw_event->timeStamp;
+	double rx_process_delay = convertdevicetimetosec(delta_t)*1000;
+
+	//time from system process rx to system frame sync
+	uint32 fs_process_delay = get_dt32(time_now, inst->timeofRxCallback);
+
+
+	//TODO test with different data rates, should set slot length according to data rate!
+	//NOTE: this is pretty close but can possibly be improved
+	//initial differences are about 1 to 2 ms, but when using FS_AVERAGE, the differences settle to about 20 microseconds
+	uint32 txrx_delay = //this->slotStartDelay //timeSinceFrameStart is now updated after the slotStartDelay
+						+ tx_antenna_delay
+						+ inst->frameLengths_us[INF]/1000
+						+ (uint32)rx_process_delay
+						+ fs_process_delay;
+
+	//NOTE: treat each port tick as about a millisecond.
+	//TODO handle number wrapping
+	this->uwbFrameStartTimes[srcIndex] = time_now - timeSinceFrameStart - txrx_delay;
+
+
+	uint32 less = timeSinceFrameStart
+			      //+ this->slotStartDelay
+			      + tx_antenna_delay
+			      + inst->frameLengths_us[INF]/1000
+			      + (uint32)rx_process_delay
+			      + fs_process_delay;
+
+
+	if(mode == FS_ADOPT)
+	{
+		this->uwbFrameStartTimes[0] = this->uwbFrameStartTimes[srcIndex];
+		this->lastSlotStartTime = this->uwbFrameStartTimes[srcIndex] + timeSinceFrameStart; //TODO handle number wrapping...
+	}
+	else if(mode == FS_AVERAGE)
+	{
+		uint32 myFramelengthDuration = this->uwbListTDMAInfo[0].framelength*this->slotDuration;
+		uint32 myTimeSinceFrameStart = get_dt32(this->uwbFrameStartTimes[0], time_now);
+
+		if(this->uwbListTDMAInfo[0].framelength <= framelength)
+		{
+			uint32 hisTimeSinceFrameStartMod = (timeSinceFrameStart + txrx_delay)%myFramelengthDuration;
+
+			if(myTimeSinceFrameStart > hisTimeSinceFrameStartMod)
+			{
+				uint32 diff = myTimeSinceFrameStart - hisTimeSinceFrameStartMod;
+				this->uwbFrameStartTimes[0] += diff/2;
+				this->lastSlotStartTime += diff/2;
+			}
+			else
+			{
+				uint32 diff = hisTimeSinceFrameStartMod - myTimeSinceFrameStart;
+				this->uwbFrameStartTimes[0] -= diff/2;
+				this->lastSlotStartTime -= diff/2;
+			}
+		}
+		else
+		{
+			uint32 hisFramelengthDuration = framelength*this->slotDuration;
+			uint32 myTimeSinceFrameStartMod = (myTimeSinceFrameStart - txrx_delay)%hisFramelengthDuration;
+
+			if(timeSinceFrameStart > myTimeSinceFrameStartMod)
+			{
+				uint32 diff = timeSinceFrameStart - myTimeSinceFrameStartMod;
+				this->uwbFrameStartTimes[0] -= diff/2;
+				this->lastSlotStartTime -= diff/2;
+			}
+			else
+			{
+				uint32 diff = myTimeSinceFrameStartMod - timeSinceFrameStart;
+				this->uwbFrameStartTimes[0] += diff/2;
+				this->lastSlotStartTime += diff/2;
+			}
+		}
+	}
+}
+
+
+static bool tx_select(struct TDMAHandler *this) //TODO handle unsuccessful add
+{
+//	uint8 debug_msg[100];
+//	int n = sprintf((char *)&debug_msg, "tx_select,");
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+
+	uint32 time_now = portGetTickCnt();
+	uint32 offset = 0;
+	//force number wrapping in case the timestamp is getting close to wrapping
+	if(time_now > 4000000000){
+		offset = 1000000000;
+	}
+	uint32 time_now_offset = time_now + offset;
+
+	//DISCOVERY pauses for BLINK_DELAY <-added
+//	if(this->waitForInf == TRUE || this->waitForRngInit == TRUE)
+//	{
+//		return FALSE;
+//	}
+
+	int uwb_index = 255;
+
+	if(inst->mode == DISCOVERY)
+	{
+		if(this->discovery_mode == WAIT_INF_REG)
+		{
+			//start blinking if enough time has passed since entering DISCOVERY mode
+			uint32 timeSinceDiscoverStart = get_dt32(this->discoveryStartTime, time_now);
+
+//			uint8 debug_msg[100];
+//			int n = sprintf((char *)&debug_msg, "discovery wait inf reg");
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
+
+	//		uint8 debug_msg[100];
+	//		int n = sprintf((char *)&debug_msg, "timeSinceDiscoverStart %lu, maxFrameDuration %lu ", timeSinceDiscoverStart, maxFrameDuration);
+	//		send_usbmessage(&debug_msg[0], n);
+	//		usb_run();
+
+			if(timeSinceDiscoverStart > this->waitInfDuration)
+			{
+				//enforce blink period
+				uint32 timeSinceLastBlink = get_dt32(this->last_blink_time, time_now);
+
+	//			uint8 debug_msg[100];
+	//			int n = sprintf((char *)&debug_msg, "timeSinceLastBlink %lu, BLINK_PERIOD_MS %lu ", timeSinceLastBlink, (uint32)BLINK_PERIOD_MS);
+	//			send_usbmessage(&debug_msg[0], n);
+	//			usb_run();
+
+				if(timeSinceLastBlink  > (uint32)BLINK_PERIOD_MS + (uint32)(rand() % 100))
+				{
+					//time to blink
+					uwb_index = 255;
+					this->set_discovery_mode(this, WAIT_RNG_INIT, time_now);
+				}
+				else
+				{
+					//not time to blink yet, keep waiting for RNG_INIT
+					inst->wait4ack = 0;
+					inst->testAppState = TA_RXE_WAIT;
+					return TRUE;
+				}
+			}
+			else
+			{
+				//shouldn't be in this mode, should be listening for INF messages
+				inst->wait4ack = 0;
+				inst->testAppState = TA_RXE_WAIT;
+				return TRUE;
+			}
+		}
+//		else if(this->discovery_mode == WAIT_SEND_SUG)//TODO left off here
+		else if(this->discovery_mode == SEND_SUG)//TODO left off here
+		{
+//			uint8 debug_msg[100];
+//			int n = sprintf((char *)&debug_msg, "discovery send sug");
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
+
+			//get time since slot start and make sure that's greater than delay
+			uint32 timeSinceSlotStart = get_dt32(this->lastSlotStartTime, time_now);
+
+			//make sure that we are in slot 0
+
+			if(timeSinceSlotStart <= this->slotStartDelay)
+			{
+				uwb_index = -1;
+			}
+			else
+			{
+				//TODO figure out how to make sure we send our SUG packet at the right time...
+				inst->wait4ack = 0;
+//				inst->testAppState = TA_TXSUG_WAIT_SEND; //TODO fold into INF_WAIT_SEND if possible
+				inst->testAppState = TA_TXINF_WAIT_SEND;
+				inst->uwbToRangeWith = (uint8)255;
+				return TRUE;
+			}
+		}
+		else
+		{
+			return FALSE;
+		}
+	}
+	else if(inst->mode == TAG)
+	{
+
+//		uint8 debug_msg[100];
+//		int n = sprintf((char *)&debug_msg, "tag");
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
+
+		//get time since slot start and make sure that's greater than delay
+		uint32 timeSinceSlotStart = get_dt32(this->lastSlotStartTime, time_now);
+
+
+		//TAG pauses for INF_POLL_DELAY <-added at beginning of slot
+//		if(this->poll_delay(this, time_now_offset, offset) == TRUE)
+		if(timeSinceSlotStart <= this->slotStartDelay)
+		{
+			uwb_index = -1;
+		}
+		else
+		{
+			//check which neighbor UWB hasn't been ranged with
+			uint32 timeSinceOldestRange = 0;
+			for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self
+			{
+				if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR)
+				{
+					uint32 timeSinceRange = get_dt32(inst->lastRangeTimeStamp[i], time_now);
+					if(timeSinceRange > timeSinceOldestRange)
+					{
+						timeSinceOldestRange = timeSinceRange;
+						uwb_index = i;
+					}
+				}
+			}
+
+			if(uwb_index == 255 && inst->uwbListLen > 0)
+			{
+				uwb_index = 1;
+			}
+		}
+
+	}
+	else
+	{
+		//ANCHOR shouldn't be in this mode, should be listening for INF and POLL
+		inst->testAppState = TA_RXE_WAIT;
+		return TRUE;
+	}
+
+//	debug_msg[100];
+//	n = sprintf((char *)&debug_msg, "selected index %i ", uwb_index);
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
+
+	if(uwb_index < 1 || this->infPollSentThisSlot == TRUE){
+		//do nothing
+		//TODO would be best to sleep until next possible poll and then select again...
+//		done = INST_DONE_WAIT_FOR_NEXT_EVENT; //TODO make sure that this is the right thing to do.
+
+//		debug_msg[100];
+//		n = sprintf((char *)&debug_msg, "1");
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
+
+		return FALSE;
+
+	}else if(uwb_index > 254){
+		inst->testAppState = TA_TXBLINK_WAIT_SEND;
+		inst->uwbToRangeWith = (uint8)255;
+
+//		debug_msg[100];
+//		n = sprintf((char *)&debug_msg, "2");
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
+
+	}else{
+
+//		debug_msg[100];
+//		n = sprintf((char *)&debug_msg, "3");
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
+
+		this->infPollSentThisSlot = TRUE;
+		inst->testAppState = TA_TXINF_WAIT_SEND;
+		inst->uwbToRangeWith = (uint8)uwb_index;
+	}
+
+	return TRUE;
+}
+
+
+static bool check_blink(struct TDMAHandler *this)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+	bool retval = FALSE;
+
+	if(inst->mode == DISCOVERY && this->discovery_mode == WAIT_INF_REG)
+	{
+		uint32 time_now = portGetTickCnt();
+		uint32 timeSinceDiscoveryStart = get_dt32(this->discoveryStartTime, time_now);
+		if(timeSinceDiscoveryStart > this->maxFramelength*this->slotDuration )
+		{
+//			uint8 debug_msg[100];
+//			int n = sprintf((char *)&debug_msg, "in RX_WAIT_DATA, portGetTickCnt(): %lu, inst->last_blink_time: %lu, BLINK_PERIOD_MS: %lu", portGetTickCnt(), inst->last_blink_time, (uint32)BLINK_PERIOD_MS);
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
+
+			uint32 timeSinceBlink = get_dt32(this->last_blink_time, time_now);
+			if(timeSinceBlink > (uint32)BLINK_PERIOD_MS + (uint32)(rand()%100)){
+//				uint8 debug_msg[100];
+//				int n = sprintf((char *)&debug_msg, "in RX_WAIT_DATA, siwtch to TA_TX_SELECT");
+//				send_usbmessage(&debug_msg[0], n);
+//				usb_run();
+
+//				this->discovery_mode = WAIT_RNG_INIT;
+				retval = TRUE;
+			}
+		}
+	}
+
+	return retval;
+}
+
+static void populate_inf_msg(struct TDMAHandler *this, uint8 inf_msg_type)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+
+	int num_neighbors = instfindnumactiveneighbors(inst);
+	int num_hidden = instfindnumactivehidden(inst);
+	uint32 time_now = portGetTickCnt();
+
+	//fcode
+	int msgDataIndex = FCODE;
+	memcpy(&inst->inf_msg.messageData[msgDataIndex], &inf_msg_type, sizeof(uint8));
+
+
+	//time since frame start
+	//populated directly before being sent
+//	msgDataIndex = TDMA_TSFS;
+//	uint32 timeSinceFrameStart = get_dt32(this->uwbFrameStartTimes[0], time_now); //TODO handle number wrapping
+//	memcpy(&inst->inf_msg.messageData[msgDataIndex], &timeSinceFrameStart, sizeof(uint32));
+
+
+//	uint8 debug_msg[100];
+//	 int n = sprintf((char*)&debug_msg[0], "TX MSG_INF timeSinceFrameStart: %lu", timeSinceFrameStart);
+//	 send_usbmessage(&debug_msg[0], n);
+//	 usb_run();
+
+	//number of neighbors
+	msgDataIndex = TDMA_NUMN;
+	memcpy(&inst->inf_msg.messageData[msgDataIndex], &num_neighbors, 1);
+
+	//number of hidden neighbors
+	msgDataIndex = TDMA_NUMH;
+	memcpy(&inst->inf_msg.messageData[msgDataIndex], &num_hidden, 1);
+
+
+	//self framelength
+	msgDataIndex = TDMA_FRAMELENGTH;
+	memcpy(&inst->inf_msg.messageData[msgDataIndex], &this->uwbListTDMAInfo[0].framelength, 1);
+
+	//self number of slots
+	msgDataIndex = TDMA_NUMS;
+	memcpy(&inst->inf_msg.messageData[msgDataIndex], &this->uwbListTDMAInfo[0].slotsLength, 1);
+	msgDataIndex++;
+
+	//self slot assignments
+	for(int s = 0; s < this->uwbListTDMAInfo[0].slotsLength; s++)
+	{
+		memcpy(&inst->inf_msg.messageData[msgDataIndex], &this->uwbListTDMAInfo[0].slots[s], 1);
+		msgDataIndex++;
+	}
+
+	//neighbor address, framelength, number of slots, and slot assignments
+	for(int i = 1; i < inst->uwbListLen; i++) //slot 0 reserved for self
+	{
+		if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR)
+		{
+			struct TDMAInfo *info = &this->uwbListTDMAInfo[i];
+
+			//address
+			memcpy(&inst->inf_msg.messageData[msgDataIndex], &inst->uwbList[i][0], inst->addrByteSize);
+			msgDataIndex += inst->addrByteSize;
+
+			//framelength
+			memcpy(&inst->inf_msg.messageData[msgDataIndex], &info->framelength, 1);
+			msgDataIndex++;
+
+			//number of slots
+			memcpy(&inst->inf_msg.messageData[msgDataIndex], &info->slotsLength, 1);
+			msgDataIndex++;
+
+			//slot assignments
+			for(int s = 0; s < info->slotsLength; s++)
+			{
+				memcpy(&inst->inf_msg.messageData[msgDataIndex], &info->slots[s], 1);
+				msgDataIndex++;
+			}
+		}
+	}
+
+	//hidden address, framelength, number of slots, and slot assignments
+	for(int i = 1; i < inst->uwbListLen; i++) //slot 0 reserved for self
+	{
+		if(inst->uwbListType[i] == UWB_LIST_HIDDEN)
+		{
+			struct TDMAInfo *info = &this->uwbListTDMAInfo[i];
+
+			//address
+			memcpy(&inst->inf_msg.messageData[msgDataIndex], &inst->uwbList[i][0], inst->addrByteSize);
+			msgDataIndex += inst->addrByteSize;
+
+			//framelength
+			memcpy(&inst->inf_msg.messageData[msgDataIndex], &info->framelength, 1);
+			msgDataIndex++;
+
+			//number of slots
+			memcpy(&inst->inf_msg.messageData[msgDataIndex], &info->slotsLength, 1);
+			msgDataIndex++;
+
+			//slot assignments
+			for(int s = 0; s < info->slotsLength; s++)
+			{
+				memcpy(&inst->inf_msg.messageData[msgDataIndex], &info->slots[s], 1);
+				msgDataIndex++;
+			}
+		}
+	}
+
+
+#if (USING_64BIT_ADDR==1)
+			this->infMessageLength = msgDataIndex + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;
+#else
+			this->infMessageLength = msgDataIndex + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+#endif
+
+}
+
+
+static void update_inf_tsfs(struct TDMAHandler *this)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+	uint32 time_now = portGetTickCnt();
+	int msgDataIndex = TDMA_TSFS;
+	uint32 timeSinceFrameStart = get_dt32(this->uwbFrameStartTimes[0], time_now); //TODO handle number wrapping
+	memcpy(&inst->inf_msg.messageData[msgDataIndex], &timeSinceFrameStart, sizeof(uint32));
+}
+
+
+////TODO
+////while collecting, build/deconflict slotAssignments...
+////when receive a INF_UPDATE or INF_SUG, rebuild/deconflict slotAssignments
+////when timeout, rebuild/deconflict slotAssignments
+//static void rebuild_slot_assignments(struct TDMAHandler *this)
+//{
+//	uint8 unassigned = 255;
+//	for(int i = 0; i < this->maxFramelength; i++)
+//	{
+//		memcpy(&this->slotAssignments[i], &unassigned, sizeof(uint8));
+//	}
+//	this->framelength = MIN_FRAMELENGTH;
+//
+//
+//	//dont forget to include my own assignments...
+//	for(int i = 0; i < this->mySlotsLength; i++)
+//	{
+//		bool double_frame = FALSE;
+//		uint8 slot = this->mySlots[i];
+//
+//		//check if slot is taken
+//		if(slot >= this->framelength)
+//		{
+//			uint8 mod_slot = slot%this->framelength;
+//			if(mod_slot == 0)
+//			{
+//				//slots not allowed to be assigned to the zeroth slot
+//				double_frame = TRUE;
+//			}
+//			else
+//			{
+//				if(memcmp(&this->slotAssignments[mod_slot], &unassigned, sizeof(uint8)) == 0)
+//				{
+//					//slot not assigned
+//					memcpy(&this->slotAssignments[mod_slot], &i, sizeof(uint8));
+//				}
+//				else if(memcmp(&this->slotAssignments[mod_slot], &i, sizeof(uint8)) != 0)
+//				{
+//					//already assigned to another UWB,
+//					//double the frame and start over!(?) should I instead consider framelengths and such?
+//					double_frame = TRUE;
+//				}
+//			}
+//
+//		}
+//		else if(slot_j < this->framelength)
+//		{
+//			while(slot_j < this->framelength)
+//			{
+//				if(memcmp(&this->slotAssignments[slot_j], &unassigned, sizeof(uint8)) == 0)
+//				{
+//					//slot not assigned
+//					memcpy(&this->slotAssignments[slot_j], &i, sizeof(uint8));
+//				}
+//				else if(memcmp(&this->slotAssignments[slot_j], &i, sizeof(uint8)) != 0)
+//				{
+//					//already assigned to another UWB,
+//					//double the frame and start over!(?) should I instead consider framelengths and such?
+//					double_frame = TRUE;
+//					break;
+//				}
+//				slot_j += framelength_i;
+//			}
+//		}
+//
+//		if(double_frame == TRUE)
+//		{
+//			this->framelength *= 2;
+//			i = 0;
+//			j = 0;
+//		}
+//
+//
+//	}
+//
+//	//getting stuck in here. this->framelength sometimes increases till overflow and gets set to 0
+//	for(int i = 0; i < inst->uwbListLen; i++)
+//	{
+//		if(inst->uwbListType[i] != UWB_LIST_INACTIVE)
+//		{
+//			uint8 framelength_i = this->uwbFramelengths[i];
+//			for(int j = 0; j < this->uwbListSlotsLengths[i]; j++)
+//			{
+//				//get slot
+//				uint8 slot_j;
+//				bool double_frame = FALSE;
+//				memcpy(&slot_j, &this->uwbListSlots[i][j], 1);
+//
+//
+//				//check if slot is taken
+//				if(slot_j >= this->framelength)
+//				{
+//					uint8 mod_slot = slot_j%this->framelength;
+//					if(mod_slot == 0)
+//					{
+//						//slots not allowed to be assigned to the zeroth slot
+//						double_frame = TRUE;
+//					}
+//					else
+//					{
+////						if(memcmp(&this->slotAssignments[mod_slot], &zero, sizeof(uint8)) == 0)
+//						if(memcmp(&this->slotAssignments[mod_slot], &unassigned, sizeof(uint8)) == 0)
+//						{
+//							//slot not assigned
+//							memcpy(&this->slotAssignments[mod_slot], &i, sizeof(uint8));
+//						}
+//						else if(memcmp(&this->slotAssignments[mod_slot], &i, sizeof(uint8)) != 0)
+//						{
+//							//already assigned to another UWB,
+//							//double the frame and start over!(?) should I instead consider framelengths and such?
+//							double_frame = TRUE;
+//						}
+//					}
+//
+//				}
+//				else if(slot_j < this->framelength)
+//				{
+//					while(slot_j < this->framelength)
+//					{
+//						if(memcmp(&this->slotAssignments[slot_j], &unassigned, sizeof(uint8)) == 0)
+//						{
+//							//slot not assigned
+//							memcpy(&this->slotAssignments[slot_j], &i, sizeof(uint8));
+//						}
+//						else if(memcmp(&this->slotAssignments[slot_j], &i, sizeof(uint8)) != 0)
+//						{
+//							//already assigned to another UWB,
+//							//double the frame and start over!(?) should I instead consider framelengths and such?
+//							double_frame = TRUE;
+//							break;
+//						}
+//						slot_j += framelength_i;
+//					}
+//				}
+//
+//				if(double_frame == TRUE)
+//				{
+//					this->framelength *= 2;
+//					i = 0;
+//					j = 0;
+//				}
+//
+//	//			uint16 uwbShortAdd = address64to16(&inst->uwbList[i][0]);
+//	//			uint8 index = msgDataIndex + 2*this->uwbListSlots[i][j];
+//	//			memcpy(&inst->inf_msg.messageData[msgDataIndex + (int)(inst->addrByteSize*this->uwbListSlots[i][j])], &uwbShortAdd, 2);
+//			}
+//		}
+//
+//	}
+//
+//
+//}
+
+
+//Procedure for processing INF SUG, INF REG, and INF UPDATE
+//1. Check for differences with locally stored TDMA assignment information
+//		(a) exit if none exist
+//2. Drop all slot assignments for self, neighbor, hidden, and twice hidden nodes that appear
+//	 in the INF message
+//3. Copy all assignments for self, neighbors, hidden, and twice hidden nodes that appear
+//	 in the INF message
+//4. Check for conflicts with slot assignments for nodes not contained in the INF message.
+//		(a) if conflicts exist and self node is one of the conflicts, release all slot assignments
+//			from self and follow the procedure for a new node (Section 1.1), skipping the
+//			collect INF REG step.
+//		(b) if conflicts exist and node is not one of the conflicts, deconflict according to 1.2
+//5. Send INF UPDATE message at beginning of allocated slot (handled elsewhere)
+
+//process types... 1.) clear all and copy 2.) clear mentioned, copy 3.) copy
+//returns TRUE if a change was made to the TDMA assingments, FALSE if invalid message FCODE or process mode or if no TDMA changes made
+static bool process_inf_msg(struct TDMAHandler *this, uint8 *messageData, uint8 srcIndex, INF_PROCESS_MODE mode)
+{
+	//NOTE: this function does not handle TDMA deconflict
+
+	bool tdma_modified = FALSE;
+
+	if((mode != CLEAR_ALL_COPY)     && //happens when we creat a new network
+	   (mode != CLEAR_LISTED_COPY)	&& //happens most of the time while processing
+	   (mode != COPY))				   //happens when collecting inf messages
+	{
+		//only process if valid mode supplied
+		return FALSE;
+	}
+
+	uint8 inf_msg_type;
+	memcpy(&inf_msg_type, &messageData[FCODE], 1);
+
+	if((inf_msg_type != RTLS_DEMO_MSG_INF_REG)	  &&
+	   (inf_msg_type != RTLS_DEMO_MSG_INF_UPDATE) &&
+	   (inf_msg_type != RTLS_DEMO_MSG_INF_INIT)   &&
+	   (inf_msg_type != RTLS_DEMO_MSG_INF_SUG))
+	{
+		//only process INF messages
+		return FALSE;
+	}
+
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+//	uint8 srcIndex = instgetuwblistindex(inst, &srcAddr[0], inst->addrByteSize);
+	inst->uwbListType[srcIndex] = UWB_LIST_NEIGHBOR;
+
+	uint32 timeSinceFrameStart;
+	uint8 numNeighbors;
+	uint8 numHidden;
+	uint8 framelength;
+	uint8 numSlots;
+	uint8 slot;
+	struct TDMAInfo *info;
+	uint8 address[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+//	uint8 uwb_index;
+
+	memcpy(&timeSinceFrameStart, &messageData[TDMA_TSFS], sizeof(timeSinceFrameStart));
+	memcpy(&numNeighbors, &messageData[TDMA_NUMN], 1);
+	memcpy(&numHidden, &messageData[TDMA_NUMH], 1);
+	memcpy(&framelength, &messageData[TDMA_FRAMELENGTH], 1);
+	memcpy(&numSlots, &messageData[TDMA_NUMS], 1);
+
+	int msgDataIndex = TDMA_NUMS + 1;
+
+	//TODO have deconflict mode???
+	bool uwbListInMsg[UWB_LIST_SIZE];
+	for(int i = 0; i < inst->uwbListLen; i++)
+	{
+		uwbListInMsg[i] = FALSE;
+	}
+
+	if(mode == CLEAR_ALL_COPY)
+	{
+		//clear all TDMA assignments
+		this->tdma_free_all_slots(this);
+		tdma_modified = TRUE;
+	}
+//	else if(mode == CLEAR_LISTED_COPY)
+//	{
+//		//first check for differences and exit if none exist...
+//		if(this->check_tdma_diff(this, messageData, srcIndex) == FALSE)
+//		{
+//			return FALSE;
+//		}
+//	}
+
+	msgDataIndex = TDMA_NUMS + 1;
+	//copy slot assignments for source UWB
+	info = &this->uwbListTDMAInfo[srcIndex];
+	if(framelength != info->framelength)
+	{
+		tdma_modified = TRUE;
+	}
+
+	if(mode == CLEAR_LISTED_COPY)
+	{
+		this->free_slots(info); //do after cheking framelength because framelength will be reset
+	}
+	info->framelength = MAX(framelength, info->framelength);
+
+	for(int s = 0; s < numSlots; s++)
+	{
+		memcpy(&slot, &messageData[msgDataIndex], 1);
+		msgDataIndex++;
+
+		if(this->assign_slot(info, slot) == TRUE)
+		{
+			tdma_modified = TRUE;
+		}
+	}
+	uwbListInMsg[srcIndex] = TRUE;
+
+	for(int i = 0; i < numNeighbors; i++)
+	{
+		memcpy(&address, &messageData[msgDataIndex], inst->addrByteSize);
+		msgDataIndex += inst->addrByteSize;
+
+		uint8 uwb_index = instgetuwblistindex(inst, &address[0], inst->addrByteSize);
+		if(uwb_index != 0) //0 reserved for self
+		{
+			if(inst->uwbListType[uwb_index] == UWB_LIST_INACTIVE || inst->uwbListType[uwb_index] == UWB_LIST_TWICE_HIDDEN)
+			{
+				inst->uwbListType[uwb_index] = UWB_LIST_HIDDEN;
+			}
+		}
+
+		info = &this->uwbListTDMAInfo[uwb_index];
+		uwbListInMsg[uwb_index] = TRUE;
+
+
+
+
+		memcpy(&framelength, &messageData[msgDataIndex], 1);
+		if(framelength != info->framelength)
+		{
+			tdma_modified = TRUE;
+		}
+		msgDataIndex++;
+
+		if(mode == CLEAR_LISTED_COPY)
+		{
+			this->free_slots(info); //do after checking framelength because framelength reset
+		}
+		info->framelength = MAX(framelength, info->framelength);
+
+
+		memcpy(&numSlots, &messageData[msgDataIndex], 1);
+		msgDataIndex++;
+
+		for(int s = 0; s < numSlots; s++)
+		{
+			memcpy(&slot, &messageData[msgDataIndex], 1);
+			msgDataIndex++;
+
+			if(this->assign_slot(info, slot) == TRUE)
+			{
+				tdma_modified = TRUE;
+			}
+		}
+	}
+
+	for(int i = 0; i < numHidden; i++)
+	{
+		memcpy(&address, &messageData[msgDataIndex], inst->addrByteSize);
+		msgDataIndex += inst->addrByteSize;
+
+		uint8 uwb_index = instgetuwblistindex(inst, &address[0], inst->addrByteSize);
+		if(uwb_index != 0)//0 reserved for self
+		{
+			if(inst->uwbListType[uwb_index] == UWB_LIST_INACTIVE)
+			{
+				inst->uwbListType[uwb_index] = UWB_LIST_TWICE_HIDDEN;
+			}
+		}
+
+		uwbListInMsg[uwb_index] = TRUE;
+		info = &this->uwbListTDMAInfo[uwb_index];
+
+		memcpy(&framelength, &messageData[msgDataIndex], 1);
+		if(framelength != info->framelength)
+		{
+			tdma_modified = TRUE;
+		}
+
+		if(mode == CLEAR_LISTED_COPY)
+		{
+			this->free_slots(info); //do after checking for difference because will reset framelength as well
+		}
+
+		info->framelength = MAX(framelength, info->framelength);
+		msgDataIndex++;
+
+		memcpy(&numSlots, &messageData[msgDataIndex], 1);
+		msgDataIndex++;
+
+		for(int s = 0; s < numSlots; s++)
+		{
+			memcpy(&slot, &messageData[msgDataIndex], 1);
+			msgDataIndex++;
+
+			if(this->assign_slot(info, slot) == TRUE) //the only problem i see with this is that it does not give me a good way to isolate which ones were or weren't modified, this is a problem for deconflict logic...
+			{
+				tdma_modified = TRUE;
+			}
+		}
+	}
+
+
+	//handle deconflict???
+	if(mode == CLEAR_LISTED_COPY)
+	{
+		//deconflict uncopied against copied. (excluding self)
+		for(int i = 1; i < inst->uwbListLen; i++)
+		{
+			for(int j = i + 1; j < inst->uwbListLen; j++)
+			{
+				if(uwbListInMsg[i] == FALSE && uwbListInMsg[j] == TRUE)
+				{
+
+					if((inst->uwbListType[i] == UWB_LIST_NEIGHBOR && inst->uwbListType[j] == UWB_LIST_NEIGHBOR) ||
+					   (inst->uwbListType[i] == UWB_LIST_NEIGHBOR && inst->uwbListType[j] == UWB_LIST_HIDDEN)   ||
+					   (inst->uwbListType[j] == UWB_LIST_NEIGHBOR && inst->uwbListType[i] == UWB_LIST_NEIGHBOR) ||
+					   (inst->uwbListType[j] == UWB_LIST_NEIGHBOR && inst->uwbListType[i] == UWB_LIST_HIDDEN))
+					{
+						//TODO make sure this is okay. will i need to ensure the assignments from the message are maintained?
+						this->deconflict_uwb_pair(this, &this->uwbListTDMAInfo[i], &this->uwbListTDMAInfo[j]);
+					}
+				}
+			}
+		}
+
+		//check if self has any conflicts
+		if(this->self_conflict(this))
+		{
+			//if so, release all assignments from self
+			this->free_slots(&this->uwbListTDMAInfo[0]);
+
+			//find self a new slot assignment
+			this->find_assign_slot(this);
+
+			tdma_modified = TRUE;
+		}
+	}
+
+
+	return tdma_modified;
+
+	//handle TDMA frame sync
+
+	//TODO keep this but turn back on, dw_event not declared...
+
+//	//account for the delay between transmission and reception of the INF message
+//	//TODO make this a function of the data rate as well!
+//	//NOTE experimentally found this number to be +- 1 millisecond for some reason. //TODO figure out why
+//	//experimentally found formula is 0.079667x + 0.85611
+//	uint32 txrx_delay = (uint32)(0.079667*(float)(dw_event->rxLength) + 0.85611); //TODO make this function of message length!
+//
+//
+//	tdma_handler->uwbFrameStartTimes[srcIndex] = time_now - (timeSinceFrameStart + txrx_delay);
+//
+//
+//	uint32 myFramelengthDuration = tdma_handler->framelength*tdma_handler->slotDuration;
+//	uint32 myTimeSinceFrameStart = get_dt32(tdma_handler->frameStartTime, time_now);
+//
+//	//NEW
+//	if(tdma_handler->framelength <= tdma_handler->uwbFramelengths[srcIndex])
+//	{
+//		uint32 timeSinceFrameStartMod = (timeSinceFrameStart + txrx_delay)%myFramelengthDuration;
+//
+//		if(myTimeSinceFrameStart > timeSinceFrameStartMod)
+//		{
+//			uint32 diff = myTimeSinceFrameStart - timeSinceFrameStartMod;
+//			tdma_handler->frameStartTime += diff/2;
+//			tdma_handler->lastSlotStartTime += diff/2;
+//		}
+//		else
+//		{
+//			uint32 diff = timeSinceFrameStartMod - myTimeSinceFrameStart;
+//			tdma_handler->frameStartTime -= diff/2;
+//			tdma_handler->lastSlotStartTime -= diff/2;
+//
+//		}
+//	}
+//	else
+//	{
+//		uint32 hisFramelengthDuration = tdma_handler->uwbFramelengths[srcIndex]*tdma_handler->slotDuration;
+//		uint32 myTimeSinceFrameStartMod = (myTimeSinceFrameStart - txrx_delay)%hisFramelengthDuration;
+//
+//		if(timeSinceFrameStart > myTimeSinceFrameStartMod)
+//		{
+//			uint32 diff = timeSinceFrameStart - myTimeSinceFrameStartMod;
+//			tdma_handler->frameStartTime -= diff/2;
+//			tdma_handler->lastSlotStartTime -= diff/2;
+//		}
+//		else
+//		{
+//			uint32 diff = myTimeSinceFrameStartMod - timeSinceFrameStart;
+//			tdma_handler->frameStartTime += diff/2;
+//			tdma_handler->lastSlotStartTime += diff/2;
+//		}
+//	}
+
+
+
+
+}
+
+
+static bool check_tdma_diff(struct TDMAHandler *this, uint8 *messageData, uint8 *srcIndex)
+{
+	return TRUE;
+
+//	struct TDMAInfo info = &this->uwbListTDMAInfo[srcIndex];
+//
+//	if(info->framelength != framelength || info->slotsLength != numSlots)
+//	{
+//		return TRUE;
+//	}
+//
+//	for(int s = 0; s < numSlots; s++)
+//	{
+//		memcpy(&slot, &messageData[msgDataIndex], 1);
+//		msgDataIndex++;
+//
+//		if(this->slot_assigned(info, slot) == FALSE)
+//		{
+//			return TRUE;
+//		}
+//	}
+//
+//	for(int i = 0; i < numNeighbors; i++)
+//	{
+//		memcpy(&address, &messageData[msgDataIndex], inst->addrByteSize);
+//		msgDataIndex += inst->addrByteSize;
+//
+//		uint8 uwb_index = instgetuwblistindex(inst, &address[0], inst->addrByteSize);
+//		info = &this->uwbListTDMAInfo[uwb_index];
+//
+//		memcpy(&framelength, &messageData[msgDataIndex], 1);
+//		msgDataIndex++;
+//
+//		memcpy(&numSlots, &messageData[msgDataIndex], 1);
+//		msgDataIndex++;
+//
+//		if(info->framelength != framelength || info->slotsLength != numSlots)
+//		{
+//			return TRUE;
+//		}
+//
+//		for(int s = 0; s < numSlots; s++)
+//		{
+//			memcpy(&slot, &messageData[msgDataIndex], 1);
+//			msgDataIndex++;
+//
+//			if(this->slot_assigned(info, slot) == FALSE)
+//			{
+//				return TRUE;
+//			}
+//		}
+//	}
+//
+//	for(int i = 0; i < numHidden; i++)
+//	{
+//		memcpy(&address, &messageData[msgDataIndex], inst->addrByteSize);
+//		msgDataIndex += inst->addrByteSize;
+//
+//		uint8 uwb_index = instgetuwblistindex(inst, &address[0], inst->addrByteSize);
+//
+//		info = &this->uwbListTDMAInfo[uwb_index];
+//
+//		memcpy(&framelength, &messageData[msgDataIndex], 1);
+//		msgDataIndex++;
+//
+//		memcpy(&numSlots, &messageData[msgDataIndex], 1);
+//		msgDataIndex++;
+//
+//		if(info->framelength != framelength || info->slotsLength != numSlots)
+//		{
+//			return TRUE;
+//		}
+//
+//		for(int s = 0; s < numSlots; s++)
+//		{
+//			memcpy(&slot, &messageData[msgDataIndex], 1);
+//			msgDataIndex++;
+//
+//			if(this->slot_assigned(info, slot) == FALSE)
+//			{
+//				return TRUE;
+//			}
+//		}
+//	}
+//
+//
+//	return FALSE;
+}
+
+
+
+//TODO add conflict detection/resolution!!!
+//static void populate_sug_msg(struct TDMAHandler *this)
+//{
+//	instance_data_t *inst = instance_get_local_structure_ptr(0);
+//
+//	//if I'm here, i should clear my own assignment information
+//	if(this->mySlots != NULL && this->mySlotsLength != 0)
+//	{
+//		this->mySlotsLength = 0;
+//		free(this->mySlots);
+//		this->mySlots = NULL;
+//	}
+//	uint8 unassigned = 255;
+//	for(int i = 0; i < this->maxFramelength; i++)
+//	{
+//		memcpy(&this->slotAssignments[i], &unassigned, sizeof(uint8));
+//	}
+//	this->framelength = MIN_FRAMELENGTH;
+//
+//
+//
+//
+//	inst->inf_msg.messageData[FCODE] = RTLS_DEMO_MSG_INF_SUG;
+//	int msgDataIndex = FCODE + 1;
+//
+//	int num_neighbors = instfindnumactiveneighbors(inst);
+//	uint32 time_now = portGetTickCnt();
+//
+//
+//	//TODO build framelength after creating slot assignments...
+////	//framelength
+////	memcpy(&inst->inf_msg.messageData[msgDataIndex], &this->framelength, 1);
+//	msgDataIndex++;
+//
+//	uint32 timeSinceFrameStart = get_dt32(this->frameStartTime, time_now); //TODO handle number wrapping
+//	memcpy(&inst->inf_msg.messageData[msgDataIndex], &timeSinceFrameStart, sizeof(uint32));
+//	msgDataIndex += sizeof(timeSinceFrameStart);
+//
+////	uint8 debug_msg[100];
+////	 int n = sprintf((char*)&debug_msg[0], "TX MSG_INF timeSinceFrameStart: %lu", timeSinceFrameStart);
+////	 send_usbmessage(&debug_msg[0], n);
+////	 usb_run();
+//
+//
+//	//number of neighbors
+//	memcpy(&inst->inf_msg.messageData[msgDataIndex], &num_neighbors, 1);
+//	msgDataIndex++;
+//
+//	//neighbor addresses
+//	for(int i = 0; i < inst->uwbListLen; i++)
+//	{
+//		if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR)
+//		{
+//			memcpy(&inst->inf_msg.messageData[msgDataIndex], &inst->uwbList[i][0], inst->addrByteSize);
+//			msgDataIndex += inst->addrByteSize;
+//		}
+//	}
+//
+//	//neighbor framelength
+//	for(int i = 0; i < inst->uwbListLen; i++)
+//	{
+//		if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR)
+//		{
+//			memcpy(&inst->inf_msg.messageData[msgDataIndex], &this->uwbFramelengths[i], 1);
+//			msgDataIndex++;
+//		}
+//	}
+//
+//	//addresses in each TDMA slot
+////	for(int i = 0; i < this->framelength; i++)
+////	{
+////		memcpy(&inst->inf_msg.messageData[msgDataIndex], &this->slotAssignments[i], 2);
+////
+////		msgDataIndex += 2;
+////	}
+//
+//	//TODO check for conflicts at some point
+//
+//	//use the slotAssignements array to combine the collected information
+//	//note: try to keep framelength as small as possible
+//	//note: if we have to increase the framelength, start over!
+//
+////	uint8 mfl = this->framelength;
+////
+////	uint8 debug_msg[100];
+////	 int n = sprintf((char*)&debug_msg[0], "this->framelength: %u", this->framelength);
+////	 send_usbmessage(&debug_msg[0], n);
+////	 usb_run();
+//
+//	//getting stuck in here... somehow this->framelength is getting set to 0
+//	for(int i = 0; i < inst->uwbListLen; i++)
+//	{
+//		if(inst->uwbListType[i] != UWB_LIST_INACTIVE)
+//		{
+//			uint8 framelength_i = this->uwbFramelengths[i];
+//			for(int j = 0; j < this->uwbListSlotsLengths[i]; j++)
+//			{
+//				//get slot
+//				uint8 slot_j;
+//				bool double_frame = FALSE;
+//				memcpy(&slot_j, &this->uwbListSlots[i][j], 1);
+//
+//
+//				//check if slot is taken
+//				if(slot_j >= this->framelength)
+//				{
+//					uint8 mod_slot = slot_j%this->framelength;
+//					if(mod_slot == 0)
+//					{
+//						//slots not allowed to be assigned to the zeroth slot
+//						double_frame = TRUE;
+//					}
+//					else
+//					{
+////						if(memcmp(&this->slotAssignments[mod_slot], &zero, sizeof(uint8)) == 0)
+//						if(memcmp(&this->slotAssignments[mod_slot], &unassigned, sizeof(uint8)) == 0)
+//						{
+//							//slot not assigned
+//							memcpy(&this->slotAssignments[mod_slot], &i, sizeof(uint8));
+//						}
+//						else if(memcmp(&this->slotAssignments[mod_slot], &i, sizeof(uint8)) != 0)
+//						{
+//							//already assigned to another UWB,
+//							//double the frame and start over!(?) should I instead consider framelengths and such?
+//							double_frame = TRUE;
+//						}
+//					}
+//
+//				}
+//				else if(slot_j < this->framelength)
+//				{
+//					while(slot_j < this->framelength)
+//					{
+//						if(memcmp(&this->slotAssignments[slot_j], &unassigned, sizeof(uint8)) == 0)
+//						{
+//							//slot not assigned
+//							memcpy(&this->slotAssignments[slot_j], &i, sizeof(uint8));
+//						}
+//						else if(memcmp(&this->slotAssignments[slot_j], &i, sizeof(uint8)) != 0)
+//						{
+//							//already assigned to another UWB,
+//							//double the frame and start over!(?) should I instead consider framelengths and such?
+//							double_frame = TRUE;
+//							break;
+//						}
+//						slot_j += framelength_i;
+//					}
+//				}
+//
+//				if(double_frame == TRUE)
+//				{
+//					this->framelength *= 2;
+//					i = 0;
+//					j = 0;
+//				}
+//
+//	//			uint16 uwbShortAdd = address64to16(&inst->uwbList[i][0]);
+//	//			uint8 index = msgDataIndex + 2*this->uwbListSlots[i][j];
+//	//			memcpy(&inst->inf_msg.messageData[msgDataIndex + (int)(inst->addrByteSize*this->uwbListSlots[i][j])], &uwbShortAdd, 2);
+//			}
+//		}
+//
+//	}
+//
+//	//if we are here, then we should've successfully combined the INF message information
+//
+//
+//
+//	bool assigned = FALSE;
+//	while(assigned == FALSE)
+//	{
+//		//first try GU (Get Unassigned) slot
+//		for(int i = 1; i < this->framelength; i++)//start at i = 1 because 0 is a reserved slot
+//		{
+////			if(memcmp(&this->slotAssignments[i], &zero, sizeof(uint8)) == 0)
+//			if(memcmp(&this->slotAssignments[i], &unassigned, sizeof(uint8)) == 0)
+//			{
+//				//empty slot, assign
+//				this->assign_slot(&this->myTDMAInfo, i);
+//				assigned = TRUE;
+//			}
+//		}
+//
+//		//no open slots for GU
+//		//next try RMA (Release Multiple Assigned) slot
+//		if(assigned == FALSE)
+//		{
+//			uint8 most_slots = 1;
+//			uint8 most_slots_index = 255;
+//			uint8 release_slot = 255;
+//			uint8 assign_slot = 255;
+//			for(int i = 0; i < inst->uwbListLen; i++)
+//			{
+//				//TODO do I only need to consider neighbors or also hidden?
+//				if(inst->uwbListType[i] != UWB_LIST_INACTIVE)
+//				{
+//					uint8 uwbSlotsLen;
+//					memcpy(&uwbSlotsLen, &this->uwbListSlotsLengths[i], sizeof(uint8));
+//					if(uwbSlotsLen > most_slots)
+//					{
+//						bool slot_found = FALSE;
+//						//check if the slot to be released can be assigned within our framelength
+//						for(int j = 0; j < uwbSlotsLen; j++)
+//						{
+//							uint8 slot;
+//							memcpy(&slot, &this->uwbListSlots[i][j], sizeof(uint8));
+//							uint8 mod_slot = slot%this->framelength;
+//
+//							if(mod_slot != 0 && memcmp(&this->slotAssignments[mod_slot], &i, sizeof(uint8)) == 0)
+//							{
+//								release_slot = slot;
+//								assign_slot = mod_slot;
+//								slot_found = TRUE;
+//								break;
+//							}
+//						}
+//
+//						if(slot_found == TRUE)
+//						{
+//							most_slots =  uwbSlotsLen;
+//							most_slots_index = i;
+//						}
+//					}
+//				}
+//			}
+//
+//			if(most_slots_index != 255) //what about self? 254?
+//			{
+//				this->assign_slot(&this->myTDMAInfo, assign_slot);
+//				this->uwblist_free_slot(this, most_slots_index, release_slot);
+//				memcpy(&this->slotAssignments[assign_slot], &this->slotAssingmentSelfIndex, sizeof(uint8));
+//
+//				assigned = TRUE;
+//			}
+//		}
+//
+//		//no slots released via RMA
+//		//DF (Double Frame), and assign via GU
+//		if(assigned == FALSE)
+//		{
+//			memcpy(&this->slotAssignments[(int)this->framelength], &this->slotAssingmentSelfIndex, sizeof(uint8));
+//
+//			for(int i = 1; i < this->framelength; i++)
+//			{
+//				memcpy(&this->slotAssignments[i + (int)this->framelength], &this->slotAssignments[i], sizeof(uint8));
+//			}
+//			this->framelength *= 2;
+//
+//			assigned = TRUE;
+//		}
+//	}
+//
+//	for(int i = 0; i < this->framelength; i++)
+//	{
+//		//TODO handle the case where we are assigned to the slot
+//		uint8 slot_index;
+//		memcpy(&slot_index, &this->slotAssignments[i], sizeof(uint8));
+//		memcpy(&inst->inf_msg.messageData[msgDataIndex], &inst->uwbList[slot_index], sizeof(inst->addrByteSize));
+//		msgDataIndex += sizeof(inst->addrByteSize);
+//	}
+//
+//	memcpy(&inst->inf_msg.messageData[FCODE + 1], &this->framelength, 1);
+//
+//	dwt_setrxtimeout((uint16)0);
+////	this->usb_dump_tdma(this);
+//
+//
+//}
+
+
+//void process_sug_msg(struct TDMAHandler *this, uint8 *messageData, uint8 *srcAddr)
+//{
+//	//how to compare and integrate changes???
+//	//first add any addresses to my list
+//	instance_data_t *inst = instance_get_local_structure_ptr(0);
+//
+//	uint8 srcIndex = instgetuwblistindex(inst, &srcAddr[0], inst->addrByteSize);
+//	inst->uwbListType[srcIndex] = UWB_LIST_NEIGHBOR;
+//	uint8 neighborAddressN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+//	uint8 neighborFramelengthN;
+//	uint8 slotAddress[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+//	uint8 blankAddress[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+//	uint32 timeSinceFrameStart;
+//
+////	if(tdma_handler->discovery_mode == WAIT_INF_REG)
+////	{
+////		tdma_handler->tdma_free_all_slots(tdma_handler);
+////	}
+//
+//	int msgDataIndex = FCODE + 1;
+//	memcpy(&tdma_handler->uwbFramelengths[srcIndex], &messageData[msgDataIndex], 1);
+//	msgDataIndex++;
+//
+//	//TODO use range to help sync frame start time
+//	memcpy(&timeSinceFrameStart, &messageData[msgDataIndex], sizeof(timeSinceFrameStart));
+//	msgDataIndex += sizeof(timeSinceFrameStart);
+//
+//
+//	memcpy(&srcNumNeighbors, &messageData[msgDataIndex], 1);
+//	msgDataIndex++;
+//
+//	int fl_index_offset = (int)(inst->addrByteSize*srcNumNeighbors);
+//	for(int n = 0; n < srcNumNeighbors; n++)
+//	{
+//		int framelength_index = msgDataIndex + fl_index_offset;
+//		memcpy(&neighborAddressN, &messageData[msgDataIndex], inst->addrByteSize);
+//		memcpy(&neighborFramelengthN, &messageData[framelength_index], sizeof(neighborFramelengthN));
+//
+//		msgDataIndex += (int)inst->addrByteSize;
+//
+//		uint8 uwb_index = instgetuwblistindex(inst, &neighborAddressN[0], inst->addrByteSize);
+//		if(inst->uwbListType[uwb_index] != UWB_LIST_NEIGHBOR)
+//		{
+//			inst->uwbListType[uwb_index] = UWB_LIST_HIDDEN;
+//		}
+//
+//		tdma_handler->uwbFramelengths[uwb_index] = neighborFramelengthN;
+//	}
+//	msgDataIndex += sizeof(uint8)*srcNumNeighbors;
+//
+//
+//	//now process the slot assignments
+//	for(int i = 0; i < tdma_handler->uwbFramelengths[srcIndex]-1; i++)//zeroth slot not included in INF
+//	{
+//		uint8 slot = i + 1;
+//		memcpy(&slotAddress, &messageData[msgDataIndex], inst->addrByteSize);
+//		//see who the address belongs to
+//#if (USING_64BIT_ADDR==0)
+//		if(memcmp(&inst->uwbShortAdd, &slotAddress, inst->addrByteSize) == 0)
+//#else
+//		if(memcmp(&inst->eui64[0], &slotAddress, inst->addrByteSize) == 0)
+//#endif
+//		{
+//			//assignment is self
+//		}
+//		else
+//		{
+//			//assignment in UWB list if not unassigned
+//			if(memcmp(&inst->eui64[0], &blankAddress, inst->addrByteSize) != 0)
+//			{
+//				//find in our list (or add as hidden)
+//				uint8 uwb_index = instgetuwblistindex(inst, &slotAddress[0], inst->addrByteSize);
+//				if(inst->uwbListType[uwb_index] != UWB_LIST_NEIGHBOR)
+//				{
+//					inst->uwbListType[uwb_index] = UWB_LIST_HIDDEN;
+//				}
+//
+//				//what to do with the information???
+//				//TODO left off here!!!
+////				tdma_handler->uwblist_assign_slot(tdma_handler, uwb_index, slot);
+//			}
+//
+//
+//
+//
+//		}
+//
+//		msgDataIndex += (int)inst->addrByteSize;
+//	}
+//
+//
+//	//account for the delay between transmission and reception of the INF message
+//	//TODO make this a function of the data rate as well!
+//	//TODO experimentally found this number to be +- 1 millisecond for some reason. figure out why
+//	//experimentally found formula is 0.079667x + 0.85611
+//	uint32 txrx_delay = (uint32)(0.079667*(float)(dw_event->rxLength) + 0.85611); //TODO make this function of message length!
+//
+//
+//	tdma_handler->uwbFrameStartTimes[srcIndex] = time_now - (timeSinceFrameStart + txrx_delay);
+//
+//
+//	uint32 myFramelengthDuration = tdma_handler->framelength*tdma_handler->slotDuration;
+//	uint32 myTimeSinceFrameStart = get_dt32(tdma_handler->frameStartTime, time_now);
+//
+//	//NEW
+//	if(tdma_handler->framelength <= tdma_handler->uwbFramelengths[srcIndex])
+//	{
+//		uint32 timeSinceFrameStartMod = (timeSinceFrameStart + txrx_delay)%myFramelengthDuration;
+//
+//		if(myTimeSinceFrameStart > timeSinceFrameStartMod)
+//		{
+//			uint32 diff = myTimeSinceFrameStart - timeSinceFrameStartMod;
+//			tdma_handler->frameStartTime += diff/2;
+//			tdma_handler->lastSlotStartTime += diff/2;
+//		}
+//		else
+//		{
+//			uint32 diff = timeSinceFrameStartMod - myTimeSinceFrameStart;
+//			tdma_handler->frameStartTime -= diff/2;
+//			tdma_handler->lastSlotStartTime -= diff/2;
+//
+//		}
+//	}
+//	else
+//	{
+//		uint32 hisFramelengthDuration = tdma_handler->uwbFramelengths[srcIndex]*tdma_handler->slotDuration;
+//		uint32 myTimeSinceFrameStartMod = (myTimeSinceFrameStart - txrx_delay)%hisFramelengthDuration;
+//
+//		if(timeSinceFrameStart > myTimeSinceFrameStartMod)
+//		{
+//			uint32 diff = timeSinceFrameStart - myTimeSinceFrameStartMod;
+//			tdma_handler->frameStartTime -= diff/2;
+//			tdma_handler->lastSlotStartTime -= diff/2;
+//		}
+//		else
+//		{
+//			uint32 diff = myTimeSinceFrameStartMod - timeSinceFrameStart;
+//			tdma_handler->frameStartTime += diff/2;
+//			tdma_handler->lastSlotStartTime += diff/2;
+//		}
+//	}
+//
+//
+//
+//
+//}
+
+
+
+static bool poll_delay(struct TDMAHandler *this, uint32 time_now_offset, uint32 offset)
+{
+	bool delay = FALSE;
+
+	uint32 time_now = portGetTickCnt();
+	uint32 timeSinceSlotStart = get_dt32(this->lastSlotStartTime, time_now);
+	if(timeSinceSlotStart > this->slotStartDelay)
+	{
+		delay = FALSE;
+	}
+
+	return delay;
+}
+
+static bool slot_assigned(struct TDMAInfo *info, uint8 slot)
+{
+	bool assigned = FALSE;
+	if(info->slots != NULL && info->slotsLength != 0)
+	{
+		for(int i = 0; i < info->slotsLength; i++)
+		{
+			if(memcmp(&info->slots[i], &slot, 1) == 0)
+			{
+				assigned = TRUE;
+				break;
+			}
+		}
+	}
+
+	return assigned;
+}
+
+static bool assign_slot(struct TDMAInfo *info, uint8 slot)
+{
+	//NOTE: deconflicting happens elsewhere
+	bool retval = FALSE;
+
+	//if not assigned, increase slots size and add slot index to end of array (array is unsorted)
+	if(slot_assigned(info, slot) == FALSE)
+	{
+		uint8 *newSlots = malloc(sizeof(uint8)*(info->slotsLength + 1));
+		memcpy(&newSlots[0], &info->slots[0], sizeof(uint8)*info->slotsLength);
+		memcpy(&newSlots[info->slotsLength], &slot, 1);
+
+		free(info->slots);
+		info->slots = NULL;
+		info->slots = newSlots;
+		info->slotsLength += 1;
+
+		retval = TRUE;
+	}
+
+	return retval;
+}
+
+//finding and assigning a slot works according to the following:
+//1.) Set framelength to 4
+//2.) Get Unassigned Slots (GU)
+//		applicable if one or more open slots exist
+//		assign self all unassigned slots (except for 0th slot); exit
+//3.) Release Multiple Assigned Slots (RMA)
+//		applicable if 2.) not applicable
+//		applicable if one or more nodes has multiple slot assignments
+//		release one slot from node with greatest number of slot assignments and assign to self; exit
+//4.) Double the Frame (DF)
+//		applicable if 2.) and 3.) not applicable
+//		double own framelength and go back to 2.)
+static void find_assign_slot(struct TDMAHandler *this)
+{
+
+	//NOTE: this assumes that all other TDMAInfo stored in the TDMAHandler are not in conflict with each other
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+	struct TDMAInfo *info = &this->uwbListTDMAInfo[0];
+	bool assignment_made = FALSE;
+
+	//set framelength
+	info->framelength = 4;
+
+	//come here after DF
+	while(TRUE)
+	{
+		//GU
+		for(int i = 1; i < info->framelength; i++) //TODO make sure we dont accidentally assign to slot 0
+		{
+			bool assigned = FALSE;
+
+			for(int u = 1; u < inst->uwbListLen; u++)//0 reserved for self
+			{
+				for(int su = 0; su < this->uwbListTDMAInfo[u].slotsLength; su++)
+				{
+					uint8 slot_su;
+					memcpy(&slot_su, &this->uwbListTDMAInfo[u].slots[su], sizeof(uint8));
+					uint8 mod_slot_su = slot_su % info->framelength;
+
+					if(slot_su == i || mod_slot_su == i)
+					{
+						//slot assigned to this uwb
+						assigned = TRUE;
+						break;
+					}
+				}
+
+				if(assigned == TRUE)
+				{
+					break;
+				}
+			}
+
+			//slot not assigned, assign to self
+			if(assigned == FALSE)
+			{
+				this->assign_slot(info, i);
+				assignment_made = TRUE;
+			}
+		}
+
+		if(assignment_made == TRUE)
+		{
+			break;
+		}
+
+		//RMA
+		//find UWB with greatest number of slot assignments
+		uint8 max_assignments = 0;
+		uint8 max_uwb_index = 255;
+		for(int u = 1; u < inst->uwbListLen; u++)//0 reserved for self
+		{
+			if(this->uwbListTDMAInfo[u].slotsLength > max_assignments)
+			{
+				max_assignments = this->uwbListTDMAInfo[u].slotsLength;
+				max_uwb_index = u;
+			}
+		}
+
+		if(max_uwb_index != 255)
+		{
+			uint8 slot;
+			memcpy(&slot, &this->uwbListTDMAInfo[max_uwb_index].slots[0], sizeof(uint8));
+			uint8 mod_slot = slot % info->framelength;
+
+			this->free_slot(&this->uwbListTDMAInfo[max_uwb_index], slot);
+			this->assign_slot(info, mod_slot);
+			assignment_made = TRUE;
+		}
+
+		if(assignment_made == TRUE)
+		{
+			break;
+		}
+
+		//DF
+		info->framelength *= 2;
+	}
+}
+
+static void build_new_network(struct TDMAHandler *this)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+	uint32 time_now = portGetTickCnt();
+
+	//clear all tdma information
+	this->tdma_free_all_slots(this);
+
+	//build the initial TDMA
+	this->uwbFrameStartTimes[0] = time_now - this->slotDuration;//TODO handle timer wrapping...
+	this->lastSlotStartTime = time_now;
+	this->uwbListTDMAInfo[0].framelength = (uint8)MIN_FRAMELENGTH;
+	this->uwbListTDMAInfo[inst->uwbToRangeWith].framelength = (uint8)MIN_FRAMELENGTH;
+
+	this->assign_slot(&this->uwbListTDMAInfo[0], 1);
+	this->assign_slot(&this->uwbListTDMAInfo[inst->uwbToRangeWith],  2);
+	this->assign_slot(&this->uwbListTDMAInfo[0], 3);
+}
+
+
+static bool deconflict_slot_assignments(struct TDMAHandler *this)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+	bool conflict = FALSE;
+
+	while(TRUE)
+	{
+		bool conflict_this_iter = FALSE;
+		//first deconflict slots in neighbor, hidden, and twice hidden
+		for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self
+		{
+			if(inst->uwbListType[i] != UWB_LIST_INACTIVE)
+			{
+				for(int j = i+1; j < inst->uwbListLen; j++)
+				{
+					if(inst->uwbListType[j] != UWB_LIST_INACTIVE && j != i)
+					{
+						//first check if their list type requires deconflicting
+						if((inst->uwbListType[i] == UWB_LIST_NEIGHBOR && inst->uwbListType[j] == UWB_LIST_TWICE_HIDDEN) ||
+						   (inst->uwbListType[j] == UWB_LIST_NEIGHBOR && inst->uwbListType[i] == UWB_LIST_TWICE_HIDDEN) ||
+						   (inst->uwbListType[i] == UWB_LIST_TWICE_HIDDEN && inst->uwbListType[j] == UWB_LIST_TWICE_HIDDEN) ||
+						   (inst->uwbListType[i] == UWB_LIST_HIDDEN && inst->uwbListType[j] == UWB_LIST_HIDDEN))
+						{
+							continue;
+						}
+
+						if(this->deconflict_uwb_pair(this, &this->uwbListTDMAInfo[i],&this->uwbListTDMAInfo[j]))
+						{
+							conflict = TRUE;
+							conflict_this_iter = TRUE;
+							break;
+						}
+					}
+				}
+			}
+
+			if(conflict_this_iter)
+			{
+				break;
+			}
+		}
+
+		if(conflict_this_iter)
+		{
+			continue;
+		}
+
+
+		//next deconflict slots between self and neighbor, hidden, and twice hidden
+		for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self
+		{
+			if(inst->uwbListType[i] != UWB_LIST_INACTIVE)
+			{
+				if(this->deconflict_uwb_pair(this, &this->uwbListTDMAInfo[0], &this->uwbListTDMAInfo[i]))
+				{
+					conflict = TRUE;
+					conflict_this_iter = TRUE;
+				}
+			}
+			if(conflict_this_iter)
+			{
+				break;
+			}
+		}
+
+		if(conflict_this_iter)
+		{
+			continue;
+		}
+
+		break; //no conflicts found this iteration, break out of while loop
+	}
+
+	return conflict;
+}
+
+
+//bool indexed_deconflict_slot_assignments(struct TDMAHandler *this, bool selfDeconflict, bool *uwbListDeconflict)
+//{
+//	instance_data_t *inst = instance_get_local_structure_ptr(0);
+//	bool conflict = FALSE;
+//
+//	while(TRUE)
+//	{
+//		bool conflict_this_iter = FALSE;
+//		//first deconflict slots in neighbor, hidden, and twice hidden
+//		for(int i = 0; i < inst->uwbListLen; i++)
+//		{
+//			if(inst->uwbListType[i] != UWB_LIST_INACTIVE)
+//			{
+//				for(int j = i+1; j < inst->uwbListLen; j++)
+//				{
+//					if(inst->uwbListType[j] != UWB_LIST_INACTIVE && j != i)
+//					{
+//						//first check if their list type requires deconflicting
+//						if((inst->uwbListType[i] == UWB_LIST_NEIGHBOR && inst->uwbListType[j] == UWB_LIST_TWICE_HIDDEN) ||
+//						   (inst->uwbListType[j] == UWB_LIST_NEIGHBOR && inst->uwbListType[i] == UWB_LIST_TWICE_HIDDEN) ||
+//						   (inst->uwbListType[i] == UWB_LIST_TWICE_HIDDEN && inst->uwbListType[j] == UWB_LIST_TWICE_HIDDEN) ||
+//						   (inst->uwbListType[i] == UWB_LIST_HIDDEN && inst->uwbListType[j] == UWB_LIST_HIDDEN))
+//						{
+//							continue;
+//						}
+//
+//						if(this->deconflict_uwb_pair(this, &this->uwbListTDMAInfo[i], &this->uwbListTDMAInfo[j]))
+//						{
+//							conflict = TRUE;
+//							conflict_this_iter = TRUE;
+//							break;
+//						}
+//					}
+//				}
+//			}
+//
+//			if(conflict_this_iter)
+//			{
+//				break;
+//			}
+//		}
+//
+//		if(conflict_this_iter)
+//		{
+//			continue;
+//		}
+//
+//
+//		//next deconflict slots between self and neighbor, hidden, and twice hidden
+//		for(int i = 0; i < inst->uwbListLen; i++)
+//		{
+//			if(inst->uwbListType[i] != UWB_LIST_INACTIVE)
+//			{
+//				if(this->deconflict_uwb_pair(this, &this->myTDMAInfo, &this->uwbListTDMAInfo[i]))
+//				{
+//					conflict = TRUE;
+//					conflict_this_iter = TRUE;
+//				}
+//			}
+//			if(conflict_this_iter)
+//			{
+//				break;
+//			}
+//		}
+//
+//		if(conflict_this_iter)
+//		{
+//			continue;
+//		}
+//
+//		break; //no conflicts found this iteration, break out of while loop
+//	}
+//
+//	return conflict;
+//}
+
+
+//return true if a conflict was found
+static bool deconflict_uwb_pair(struct TDMAHandler *this, struct TDMAInfo *info_a, struct TDMAInfo *info_b)
+{
+	bool conflict = FALSE;
+
+	while(TRUE)
+	{
+		bool conflict_this_iter = false;
+
+		for(int sa = 0; sa < info_a->slotsLength; sa++)
+		{
+			uint8 slot_sa;
+			memcpy(&slot_sa, &info_a->slots[sa], 1);
+
+			for(int sb = 0; sb < info_b->slotsLength; sb++)
+			{
+				uint8 slot_sb;
+				memcpy(&slot_sb, &info_a->slots[sb], 1);
+
+
+				//check if slot is taken
+				if(slot_sa >= info_b->framelength)
+				{
+					uint8 mod_slot_sa = slot_sa%info_b->framelength;
+
+					if(mod_slot_sa == slot_sb)
+					{
+						//slot already assigned, deconflict!
+						this->deconflict_slot_pair(this, info_a, info_b, sa, sb);
+						conflict = TRUE;
+						conflict_this_iter = TRUE;
+						break;
+					}
+				}
+				else if(slot_sb >= info_a->framelength)
+				{
+					uint8 mod_slot_sb = slot_sb%info_a->framelength;
+					if(mod_slot_sb == slot_sa)
+					{
+						//slot already assigned, deconflict!
+						this->deconflict_slot_pair(this, info_a, info_b, sa, sb);
+						conflict = TRUE;
+						conflict_this_iter = TRUE;
+						break;
+					}
+				}
+				else
+				{
+					if(slot_sa == slot_sb)
+					{
+						//slot already assigned, deconflict!
+						this->deconflict_slot_pair(this, info_a, info_b, sa, sb);
+						conflict = TRUE;
+						conflict_this_iter = TRUE;
+						break;
+					}
+				}
+			}
+
+			if(conflict_this_iter)
+			{
+				break;
+			}
+		}
+
+		if(conflict_this_iter)
+		{
+			continue;
+		}
+
+		break; //no conflicts found this iterations, break while loop
+	}
+
+	return conflict;
+}
+
+
+//TODO assign reference in class struct!!! same with others written today
+static void deconflict_slot_pair(struct TDMAHandler *this, struct TDMAInfo *info_a, struct TDMAInfo *info_b, uint8 slot_idx_a, uint8 slot_idx_b)
+{
+	//procedure for deconflicting slots (PDS)
+	//1.) delete a conflicting slot
+	//		applicable if all but node with fewest slots has more than one slot assignment
+	//		release conflicting slot from all but node with fewest slots
+	//2.) divide the assignment
+	//		applicable if multiple conflicting slots between to nodes
+	//		release lowest slot from first, greatest from second
+	//3.) double the frame and divide the assignment
+	//		applicable if single conflict between two nodes and neither has another slot assignment
+	//		double the framelength of one or both and assign one slot assignment to the first and other to the second
+	//		make the change
+	//4.) if any of 1-3.) is applied, check for conflicts again, and start again at 1.)
+
+	//logic for 1.) and 2.) not explicitly programmed.
+	//Should be taken care of by repeatedly checking for conflicts and executing the code block below
+	if(info_a->slotsLength > 1 || info_b->slotsLength > 1)
+	{
+		if(info_a->slotsLength >= info_b->slotsLength)
+		{
+			//release slot from uwb_a
+			uint8 slot_a;
+			memcpy(&slot_a, &info_a->slots[slot_idx_a], sizeof(uint8));
+			this->free_slot(info_a, slot_a);
+			return;
+		}
+		else
+		{
+			//release slot from uwb_b
+			uint8 slot_b;
+			memcpy(&slot_b, &info_b->slots[slot_idx_b], sizeof(uint8));
+			this->free_slot(info_b, slot_b);
+			return;
+		}
+	}
+
+	//double the frame and divide the assignment
+	if(info_a->framelength == info_b->framelength)
+	{
+		uint8 slot_b;
+		memcpy(&slot_b, &info_b->slots[slot_idx_b], sizeof(uint8));
+		slot_b += info_b->framelength;
+		memcpy(&info_b->slots[slot_idx_b], &slot_b, sizeof(uint8));
+		info_a->framelength *= 2;
+		info_b->framelength *= 2;
+	}
+	else if(info_a->framelength > info_b->framelength)
+	{
+		uint8 slot_a;
+		memcpy(&slot_a, &info_a->slots[slot_idx_a], sizeof(uint8));
+		uint8 mod_a = slot_a % (2*info_b->framelength);
+
+		uint8 slot_b;
+		memcpy(&slot_b, &info_b->slots[slot_idx_b], sizeof(uint8));
+
+		if(mod_a == slot_b)
+		{
+			slot_b += info_b->framelength;
+			memcpy(&info_b->slots[slot_idx_b], &slot_b, sizeof(uint8));
+		}
+
+		info_b->framelength *= 2;
+	}
+	else if(info_a->framelength < info_b->framelength)
+	{
+		uint8 slot_b;
+		memcpy(&slot_b, &info_b->slots[slot_idx_b], sizeof(uint8));
+		uint8 mod_b = slot_b % (2*info_a->framelength);
+
+		uint8 slot_a;
+		memcpy(&slot_a, &info_a->slots[slot_idx_a], sizeof(uint8));
+
+		if(mod_b == slot_a)
+		{
+			slot_a += info_a->framelength;
+			memcpy(&info_a->slots[slot_idx_a], &slot_a, sizeof(uint8));
+		}
+
+		info_a->framelength *= 2;
+	}
+
+	//re-checking for conflicts handled in calling function
+}
+
+//check if this uwb has any TDMA conflicts with others in the uwbList
+static bool self_conflict(struct TDMAHandler *this)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+	struct TDMAInfo *info_a = &this->uwbListTDMAInfo[0];
+
+	for(int b = 1; b < inst->uwbListLen; b++)
+	{
+		if(inst->uwbListType[b] == UWB_LIST_NEIGHBOR ||
+		   inst->uwbListType[b] == UWB_LIST_HIDDEN   ||
+		   inst->uwbListType[b] == UWB_LIST_TWICE_HIDDEN)
+		{
+			struct TDMAInfo *info_b = &this->uwbListTDMAInfo[b];
+
+			for(int sa = 0; sa < info_a->slotsLength; sa++)
+			{
+				uint8 slot_sa;
+				memcpy(&slot_sa, &info_a->slots[sa], 1);
+
+				for(int sb = 0; sb < info_b->slotsLength; sb++)
+				{
+					uint8 slot_sb;
+					memcpy(&slot_sb, &info_a->slots[sb], 1);
+
+
+					//check if slot is taken
+					if(slot_sa >= info_b->framelength)
+					{
+						uint8 mod_slot_sa = slot_sa%info_b->framelength;
+
+						if(mod_slot_sa == slot_sb)
+						{
+							return TRUE;
+						}
+					}
+					else if(slot_sb >= info_a->framelength)
+					{
+						uint8 mod_slot_sb = slot_sb%info_a->framelength;
+						if(mod_slot_sb == slot_sa)
+						{
+							return TRUE;
+						}
+					}
+					else
+					{
+						if(slot_sa == slot_sb)
+						{
+							return TRUE;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+static void free_slot(struct TDMAInfo *info, uint8 slot)
+{
+	bool assigned = TRUE;
+
+	while(assigned == TRUE) //duplicate assignments shouldn't exist, but will make sure to remove any just in case
+	{
+		uint8 slot_index = 255;
+		assigned = FALSE;
+		if(info->slots != NULL && info->slotsLength != 0)
+		{
+			for(int i = 0; i < info->slotsLength; i++)
+			{
+				if(memcmp(&info->slots[i], &slot, sizeof(uint8)) == 0)
+				{
+					assigned = TRUE;
+					slot_index = i;
+					break;
+				}
+			}
+		}
+
+		//if assigned, remove from array
+		if(assigned == TRUE)
+		{
+			memcpy(&info->slots[slot_index], &info->slots[slot_index + 1], sizeof(uint8)*(info->slotsLength - slot_index - 1));
+			info->slotsLength -= 1;
+			if(info->slotsLength <= 0)
+			{
+				info->slotsLength = 0;
+				free(info->slots);
+				info->slots = NULL;
+			}
+		}
+	}
+
+
+	return;
+}
+
+static void free_slots(struct TDMAInfo *info)
+{
+	if(info->slots != NULL)
+	{
+		free(info->slots);
+		info->slots = NULL;
+	}
+
+	info->slotsLength = 0;
+	info->framelength = MIN_FRAMELENGTH;
+}
+
+static void uwblist_free_slots(struct TDMAHandler *this, uint8 uwb_index)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+	if(uwb_index >= inst->uwbListLen)
+	{
+		//out of bounds!
+//		uint8 debug_msg[100];
+//		 int n = sprintf((char*)&debug_msg[0], "uwblist_free_slots: uwb_index %u out of bounds", uwb_index);
+//		 send_usbmessage(&debug_msg[0], n);
+//		 usb_run();
+		return;
+	}
+
+	this->free_slots(&this->uwbListTDMAInfo[uwb_index]);
+
+	return;
+}
+
+static void tdma_free_all_slots(struct TDMAHandler *this)
+{
+	for(int i = 0; i < (int)UWB_LIST_SIZE; i++)
+	{
+		if(this->uwbListTDMAInfo[i].slots != NULL)
+		{
+			free(this->uwbListTDMAInfo[i].slots);
+			this->uwbListTDMAInfo[i].slots = NULL;
+		}
+
+		this->uwbListTDMAInfo[i].slotsLength = 0;
+		this->uwbListTDMAInfo[i].framelength = MIN_FRAMELENGTH;
+	}
+
+	return;
+}
+
+
+//TODO
+static void enter_discovery_mode(struct TDMAHandler *this)
+{
+//	instance_data_t *inst = instance_get_local_structure_ptr(0);
+//	inst->inf_msg.messageData[FCODE] = RTLS_DEMO_MSG_INF_INIT;
+
+	uint32 time_now = portGetTickCnt();
+	this->discoveryStartTime = time_now;
+	this->last_blink_time = time_now;
+	this->set_discovery_mode(this, WAIT_INF_REG, time_now);
+	this->collectInfStartTime = time_now;
+
+	this->tdma_free_all_slots(this);
+}
+
+static void set_discovery_mode(struct TDMAHandler *this, DISCOVERY_MODE discovery_mode, uint32 time_now)
+{
+	this->discovery_mode_start_time = time_now;
+	this->discovery_mode = discovery_mode;
+
+
+//	uint8 debug_msg[100];
+//	 int n = sprintf((char*)&debug_msg[0], "set_discovery_mode: %s", get_discovery_modes_string(discovery_mode));
+//	 send_usbmessage(&debug_msg[0], n);
+//	 usb_run();
+
+
+
+	switch (discovery_mode)//TODO make sure all modes are captured here...
+	{
+		case WAIT_INF_REG:
+		{
+			this->discovery_mode_duration = 0;
+			this->discovery_mode_expires = FALSE;
+			break;
+		}
+		case COLLECT_INF_REG:
+		{
+			this->collectInfStartTime = time_now;
+			this->discovery_mode_duration = this->collectInfDuration;
+			this->discovery_mode_expires = TRUE;
+			break;
+		}
+		case WAIT_INF_INIT:
+		{
+			this->discovery_mode_duration = 400;//TODO use a smart timeout value
+			this->discovery_mode_expires = TRUE;
+			break;
+		}
+		case WAIT_RNG_INIT:
+		{
+			this->discovery_mode_duration = 400;//TODO use a smart timeout value
+			this->discovery_mode_expires = TRUE;
+			break;
+		}
+		case WAIT_SEND_SUG:
+		{
+			//find common frame start time among neighbors
+			instance_data_t *inst = instance_get_local_structure_ptr(0);
+
+			//TODO handle number wrapping
+			uint32 tcommon;
+			uint32 shortestFrameDuration = this->maxFramelength*this->slotDuration;
+			uint8 numNeighbors = instfindnumactiveneighbors(inst);
+			uint32 tnext[numNeighbors];
+			uint32 latest_tnext;
+			uint8 neighborIndices[numNeighbors];
+			uint8 nidx = 0;
+
+			for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self
+			{
+				if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR)
+				{
+					neighborIndices[nidx] = i;
+					tnext[nidx] = this->uwbFrameStartTimes[i];
+					while(time_now > tnext[nidx]) //TODO handle number wrapping...
+					{
+						tnext[nidx] += this->uwbListTDMAInfo[i].framelength*this->slotDuration;
+					}
+					nidx++;
+
+					if(this->uwbListTDMAInfo[i].framelength*this->slotDuration < shortestFrameDuration)
+					{
+						shortestFrameDuration = this->uwbListTDMAInfo[i].framelength*this->slotDuration;
+					}
+				}
+			}
+
+			tcommon = tnext[0];
+			latest_tnext = tcommon;
+			bool converged = FALSE;
+			while(converged == FALSE)
+			{
+				converged = TRUE;
+				for(int i = 0; i < nidx; i++)
+				{
+					uint32 frameduration = this->uwbListTDMAInfo[neighborIndices[i]].framelength*this->slotDuration;
+					while(tnext[i] < tcommon && tcommon - tnext[i] >= frameduration) //include small buffer
+					{
+						tnext[i] += frameduration;
+					}
+
+
+					if(tnext[i] > tcommon && tnext[i] - tcommon >= shortestFrameDuration) //TODO maybe include a small buffer to account for small timing errors?
+					{
+						tcommon = tnext[i];
+						converged = FALSE;
+					}
+
+					if(tnext[i] > latest_tnext)
+					{
+						latest_tnext = tnext[i];
+					}
+				}
+			}
+
+
+			//expire as the beginning of the common frame start time
+			this->discovery_mode_duration = get_dt32(time_now, latest_tnext);
+			this->discovery_mode_expires = TRUE;
+			break;
+		}
+		case EXIT:
+		{
+			this->discovery_mode_duration = 0;
+			this->discovery_mode_expires = FALSE;
+			break;
+		}
+		default:
+		{
+			break;
+		}
+
+	}
+
+
+}
+
+static void check_discovery_mode_expiration(struct TDMAHandler *this)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+
+	if(inst->mode == DISCOVERY)
+	{
+		if(this->discovery_mode_expires == TRUE)
+		{
+			uint32 time_now = portGetTickCnt();
+			uint32 timeSinceModeStart = get_dt32(this->discovery_mode_start_time, time_now);
+			if(timeSinceModeStart > this->discovery_mode_duration)
+			{
+				//discovery mode expired
+				DISCOVERY_MODE new_mode = WAIT_INF_REG;
+				if(this->discovery_mode == COLLECT_INF_REG)
+				{
+					new_mode = WAIT_SEND_SUG;
+//					inst->testAppState = TA_TX_SELECT;
+					inst->testAppState = TA_RXE_WAIT; //still collect RNG_REPORT messages while we wait to send our SUG message
+
+					//deconflict gathered tdma info
+					this->deconflict_slot_assignments(this);
+					//assign self slot
+					this->find_assign_slot(this);
+					//construct SUG packet
+					this->populate_inf_msg(this, RTLS_DEMO_MSG_INF_SUG);
+
+					//TODO how to actually send SUG message? TA_TX_SELECT?
+					//could go directly to TA_TXSUG_WAIT_SEND and delay until start of next frame...
+					//that could remove the need for extra logic in TA_TX_SELECT...
+				}
+				else if(this->discovery_mode == WAIT_SEND_SUG)
+				{
+					inst->testAppState = TA_TX_SELECT;
+					new_mode = SEND_SUG;
+				}
+
+				this->set_discovery_mode(this, new_mode, time_now);
+			}
+		}
+	}
+}
+
+static void usb_dump_tdma(struct TDMAHandler *this)
+{
+	instance_data_t *inst = instance_get_local_structure_ptr(0);
+
+	uint8 debug_msg[20000];
+	int n = sprintf((char*)&debug_msg[0], "TDMA Handler Dump \n");
+	int n_char = n;
+
+//	n = sprintf((char*)&debug_msg[n_char], "framelength: %d, maxFramelength: %d \n", this->myTDMAInfo.framelength, this->maxFramelength);
+//	n_char += n;
+
+//	n = sprintf((char*)&debug_msg[n_char], "mySlots[%u]: ", this->myTDMAInfo.slotsLength);
+//	n_char += n;
+//	for(int i = 0; i < this->myTDMAInfo.slotsLength; i++)
+//	{
+//		uint8 slot;
+//		memcpy(&slot, &this->myTDMAInfo.slots[i], sizeof(uint8));
+//		n = sprintf((char*)&debug_msg[n_char], " %u ", slot);
+//		n_char += n;
+//	}
+//	n = sprintf((char*)&debug_msg[n_char], "\n");
+//	n_char += n;
+
+	for(int u = 0; u < inst->uwbListLen; u++)
+	{
+		n = sprintf((char*)&debug_msg[n_char], "UWB %i framelength: %u \n", u, this->uwbListTDMAInfo[u].framelength);
+		n_char += n;
+
+		n = sprintf((char*)&debug_msg[n_char], "UWB %i Slots[%u]: \n", u, this->uwbListTDMAInfo[u].slotsLength);
+		n_char += n;
+		for(int i = 0; i < this->uwbListTDMAInfo[u].slotsLength; i++)
+		{
+			uint8 slot;
+			memcpy(&slot, &this->uwbListTDMAInfo[u].slots[i], sizeof(uint8));
+			n = sprintf((char*)&debug_msg[n_char], " %u ", slot);
+			n_char += n;
+		}
+		n = sprintf((char*)&debug_msg[n_char], "\n");
+		n_char += n;
+	}
+
+
+
+	int div = 100;
+	int idx = 0;
+
+	for(int i = 0; i + div < n_char; i += div)
+	{
+		idx = i;
+		send_usbmessage(&debug_msg[i], div);
+		usb_run();
+		Sleep(10);
+	}
+	if(idx + 1 < n_char)
+	{
+		send_usbmessage(&debug_msg[idx], n_char - idx);
+		usb_run();
+	}
+
+}
+
+//uint8 get_largest_framelength(struct TDMAHandler *this)
+//{
+//	instance_data_t *inst = instance_get_local_structure_ptr(0);
+//
+//	uint8 max_framelength = MIN_FRAMELENGTH;
+//	if(this->myTDMAInfo.framelength > max_framelength)
+//	{
+//		max_framelength = this->myTDMAInfo.framelength;
+//	}
+//
+//	for(int i = 0; i < inst->uwbListLen; i++)
+//	{
+//		if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR)
+//		{
+//			if(this->uwbFramelengths[i] > max_framelength)
+//			{
+//				max_framelength = this->uwbFramelengths[i];
+//			}
+//		}
+//
+//	}
+//
+//	return max_framelength;
+//}
+
+
+static struct TDMAHandler new(){
+	struct TDMAHandler ret = {};
+
+	ret.slotDuration = 50; //TODO should be a function of the data rate and the max number of UWBs
+
+	ret.slot_transition = &slot_transition;
+	ret.frame_sync = &frame_sync;
+	ret.tx_select  = &tx_select;
+	ret.check_blink  = &check_blink;
+
+	//	ret.rebuild_slot_assignments = &rebuild_slot_assignments;
+
+	ret.populate_inf_msg = &populate_inf_msg;
+	ret.update_inf_tsfs = &update_inf_tsfs;
+	ret.process_inf_msg = &process_inf_msg;
+	ret.check_tdma_diff = &check_tdma_diff;
+//	ret.populate_sug_msg = &populate_sug_msg;	//TODO remove
+//	ret.process_sug_msg = &process_sug_msg;		//TODO remove
+
+	ret.poll_delay = &poll_delay;
+	ret.slot_assigned = &slot_assigned;
+	ret.assign_slot = &assign_slot;
+	ret.find_assign_slot = &find_assign_slot;
+	ret.build_new_network = &build_new_network;
+
+	ret.free_slot = &free_slot;
+	ret.free_slots = &free_slots;
+	ret.tdma_free_all_slots = &tdma_free_all_slots;
+	ret.uwblist_free_slots = &uwblist_free_slots;
+	ret.enter_discovery_mode = &enter_discovery_mode;
+	ret.set_discovery_mode = &set_discovery_mode;
+	ret.check_discovery_mode_expiration = &check_discovery_mode_expiration;
+	ret.usb_dump_tdma = &usb_dump_tdma;
+//	ret.get_largest_framelength = &get_largest_framelength;
+
+	ret.deconflict_slot_assignments = &deconflict_slot_assignments;
+	ret.deconflict_uwb_pair = &deconflict_uwb_pair;
+	ret.deconflict_slot_pair = &deconflict_slot_pair;
+	ret.self_conflict = &self_conflict;
+
+	uint32 time_now = portGetTickCnt();
+
+	//TODO create a function to clear the frame information!
+	//and have it called in enter_discovery function!
+
+
+	ret.maxFramelength = (uint8)MIN_FRAMELENGTH;
+	while(ret.maxFramelength < (int)UWB_LIST_SIZE + 1)
+	{
+		ret.maxFramelength *= 2;
+	}
+
+//	ret.myTDMAInfo.uwbIndex = 254; //254 reserved to identify self
+//	ret.myTDMAInfo.framelength = (uint8)MIN_FRAMELENGTH;
+//	ret.myTDMAInfo.slots = NULL;
+//	ret.myTDMAInfo.slotsLength = 0;
+
+	for(int i = 0; i < UWB_LIST_SIZE; i++)
+	{
+		ret.uwbListTDMAInfo[i].uwbIndex = i;
+		ret.uwbListTDMAInfo[i].framelength = (uint8)MIN_FRAMELENGTH;
+		ret.uwbListTDMAInfo[i].slots = NULL;
+		ret.uwbListTDMAInfo[i].slotsLength = 0;
+	}
+
+    ret.uwbFrameStartTimes[0] = time_now;
+    ret.lastSlotStartTime = time_now;
+    ret.infPollSentThisSlot = FALSE;
+    ret.slotStartDelay = 4;
+    ret.infMessageLength = 0;
+
+    ret.enter_discovery_mode(&ret);
+    ret.collectInfDuration = ret.maxFramelength*ret.slotDuration;
+    ret.waitInfDuration = ret.collectInfDuration;
+
+	return ret;
+}
+
+const struct TDMAHandlerClass TDMAHandler={.new=&new};
+
+
diff --git a/src/application/tdma_handler.h b/src/application/tdma_handler.h
new file mode 100644
index 0000000..e7a21c5
--- /dev/null
+++ b/src/application/tdma_handler.h
@@ -0,0 +1,119 @@
+#ifndef TDMA_HANDLER_H_
+#define TDMA_HANDLER_H_
+
+//#include "llist.h"
+#include "deca_types.h"
+#include "application_definitions.h"
+
+struct TDMAInfo
+{
+	uint8 uwbIndex; //TODO remove if unused
+	uint8 framelength;
+	uint8 slotsLength;
+	uint8 *slots;
+};
+
+typedef enum inf_process_mode
+{
+	CLEAR_ALL_COPY,
+	CLEAR_LISTED_COPY,
+	COPY
+}
+INF_PROCESS_MODE;
+
+typedef enum frame_sync_mode
+{
+	FS_ADOPT,
+	FS_AVERAGE
+}
+FRAME_SYNC_MODE;
+
+struct TDMAHandler
+{
+
+    //TDMA class variables
+    uint8 maxFramelength;
+	uint8 slotAssingmentSelfIndex;
+
+//	struct TDMAInfo myTDMAInfo;
+
+	struct TDMAInfo uwbListTDMAInfo[UWB_LIST_SIZE];
+
+	uint32 uwbFrameStartTimes[UWB_LIST_SIZE]; //TODO propagate the use of this
+//	uint32 frameStartTime;
+	uint32 lastSlotStartTime;
+	uint32 slotDuration;   //TODO make variable in duration based on UWB_LIST_SIZE
+	bool infPollSentThisSlot;
+
+	uint32 slotStartDelay; //time between slot start and transmission within that slot
+
+	//discovery variables
+	DISCOVERY_MODE discovery_mode;
+	uint32 last_blink_time;	   //timestamp of most recent blink
+	uint32 discoveryStartTime; //time that we started listening for other UWBs
+	uint32 discovery_mode_start_time;
+	uint32 discovery_mode_duration;
+	bool discovery_mode_expires;
+	uint32 collectInfStartTime;
+	uint32 collectInfDuration;
+	uint32 waitInfDuration;
+
+	uint16 infMessageLength;
+
+//	bool waitForRngInit;
+//	bool waitForInf;
+//	uint32 waitForInfStart;
+//	uint32 waitForRngInitStart;
+
+    //class functions
+	bool (*slot_transition)(struct TDMAHandler *this);
+//	void (*frame_sync)(struct TDMAHandler *this, uint8 *messageData, uint16 rxLength, uint8 srcIndex, FRAME_SYNC_MODE mode);
+	void (*frame_sync)(struct TDMAHandler *this, event_data_t *dw_event, uint8 *messageData, uint8 srcIndex, FRAME_SYNC_MODE mode);
+	void (*update_inf_tsfs)(struct TDMAHandler *this);
+	bool (*tx_select)(struct TDMAHandler *this);
+//	bool (*rx_accept)(struct TDMAHandler *this, uint8 uwb_index, uint8 *rxd_event, uint8 *msgu, uint8 fcode_index);
+    bool (*check_blink)(struct TDMAHandler *this);
+//    void (*rebuild_slot_assignments)(struct TDMAHandler *this);
+    void (*populate_inf_msg)(struct TDMAHandler *this, uint8 inf_msg_type);
+//    void (*process_inf_msg)(struct TDMAHandler *this); //TODO implement
+    bool (*process_inf_msg)(struct TDMAHandler *this, uint8 *messageData, uint8 srcIndex, INF_PROCESS_MODE mode);
+    bool (*check_tdma_diff)(struct TDMAHandler *this, uint8 *messageData, uint8 *srcAddr);
+//    void (*populate_sug_msg)(struct TDMAHandler *this);//TODO remove this
+//    void (*process_sug_msg)(struct TDMAHandler *this, uint8 *messageData, uint8 *srcAddr);//TODO remove this
+    bool (*poll_delay)(struct TDMAHandler *this, uint32 time_now_offset, uint32 offset);
+    void (*enter_discovery_mode)(struct TDMAHandler *this);
+    void (*set_discovery_mode)(struct TDMAHandler *this, DISCOVERY_MODE mode, uint32 time_now);
+    void (*check_discovery_mode_expiration)(struct TDMAHandler *this);
+    void (*usb_dump_tdma)(struct TDMAHandler *this);
+
+    //TODO left off here. updating messageData as well as
+    //TODO revisit anything that works with messageData!!!
+    bool (*slot_assigned)(struct TDMAInfo *info, uint8 slot);
+    bool (*assign_slot)(struct TDMAInfo *info, uint8 slot);
+    void (*free_slot)(struct TDMAInfo *info, uint8 slot);
+    void (*free_slots)(struct TDMAInfo *info);
+    void (*uwblist_free_slots)(struct TDMAHandler *this, uint8 uwb_index);
+	void (*tdma_free_all_slots)(struct TDMAHandler *this);
+	void (*find_assign_slot)(struct TDMAHandler *this);
+	void (*build_new_network)(struct TDMAHandler *this);
+
+//    void (*uwblist_collect_slot_assignment)(struct TDMAHandler *this, uint8 uwb_index, uint8 slot_index);
+
+	//run through all uwb pairs
+    bool (*deconflict_slot_assignments)(struct TDMAHandler *this); //TODO implement
+    //run through each slot of two uwbs
+    bool (*deconflict_uwb_pair)(struct TDMAHandler *this, struct TDMAInfo *info_a, struct TDMAInfo *info_b);
+    //deconflict two specific slots
+    void (*deconflict_slot_pair)(struct TDMAHandler *this, struct TDMAInfo *info_a, struct TDMAInfo *info_b, uint8 slot_idx_a, uint8 slot_idx_b);
+    bool (*self_conflict)(struct TDMAHandler *this);
+};
+
+
+extern const struct TDMAHandlerClass
+{
+	struct TDMAHandler (*new)();
+
+} TDMAHandler;
+
+
+#endif
diff --git a/src/application/tdma_scheduler.c b/src/application/tdma_scheduler.c
new file mode 100644
index 0000000..3fc6704
--- /dev/null
+++ b/src/application/tdma_scheduler.c
@@ -0,0 +1,214 @@
+#include "tdma_handler.h"
+#include "port.h"
+
+
+extern void usb_run(void);
+extern void send_usbmessage(uint8*, int);
+
+//private methods
+int tdma_node_compare(llist_node first, llist_node second)
+{
+    tdma_timing_node *first_node = (tdma_timing_node *)first;
+    tdma_timing_node *second_node = (tdma_timing_node *)second;
+
+	if(first_node->time == second_node->time)
+	{
+        return 0;
+    }
+	else if(first_node->time > second_node->time)
+	{
+        return 1;
+    }
+    else
+    {
+        return -1;
+    }
+	return 0;
+}
+
+
+bool tdma_node_equal(llist_node first, llist_node second)
+{
+    if(first == second){return true;}
+
+    return false;
+}
+
+
+//class methods
+static void set_slot(struct TDMAHandler *this)
+{
+//	uint32 time_now = portGetTickCnt();
+//	uint32 offset = 0;
+//
+//	//force number wrapping in case the timestamp is getting close to wrapping
+//	if(time_now > 4000000000){
+//		offset = 1000000000;
+////		time_now += offset;
+//	}
+//	uint32 time_now_offset = time_now + offset;
+//
+////	if(time_now_offset < this->time_reject_select + offset){
+////		return -1;
+////	}
+//
+////	uint8 debug_msg[100];
+////	int n = sprintf((char*)&debug_msg[0], "[0] %u [1] %u", this->uwb_timeout_list[0], this->uwb_timeout_list[1]);
+////	send_usbmessage(&debug_msg[0], n);
+////	usb_run();
+//
+//	//start by removing expired nodes
+//	while(true){
+//
+//		if(llist_size(this->list) == 0){break;}
+//
+//		tdma_timing_node *node = llist_get_head(this->list);
+//
+//		if(time_now_offset > node->time + node->duration + offset){ //expired
+//			llist_delete_node(this->list, node, true, NULL);
+//		}
+//		else{
+//			break;
+//		}
+//	}
+//
+//	//check if it's time to blink
+//	if(time_now_offset > this->last_blink_time + this->blink_period + offset){
+//		this->last_blink_time = time_now;
+//		return 255;
+//	}
+//
+//	//don't range if it will carry over into blink time
+//	if(time_now_offset + this->range_duration > this->last_blink_time + this->blink_period + offset){
+//		return -1;
+//	}
+//
+//	//TODO could have a set flag for this like uwb_active...
+//	int cooldown_arr[*this->uwb_list_length];
+//	memset(cooldown_arr, 0, sizeof(cooldown_arr));
+//
+//	tx_timing_node *node = llist_get_head(this->list);
+//	//dont select if it starts in or ends in a cooldown period...
+//	while(node != NULL){
+//		if(cooldown_arr[node->index] == 0)
+//		{
+//			if((time_now_offset > node->time + offset && time_now_offset < node->time + node->duration + offset) ||
+//			   (time_now_offset + this->range_duration > node->time + offset && time_now_offset + this->range_duration < node->time + node->duration + offset) )
+//			{
+//				cooldown_arr[node->index] = 1;
+//			}
+//		}
+//		node = llist_get_next(this->list, node);
+//	}
+//
+//
+//	uint8 uwb_list_len = *this->uwb_list_length;
+//	uint8 num_checked = 0;
+//	uint8 index = (this->last_select_index + 1)%uwb_list_len;
+//	while(num_checked < uwb_list_len){
+//		if(cooldown_arr[index] == 0 && this->uwb_timeout_list[index] == 0){
+//			this->last_select_index = index;
+//			this->time_reject_select = time_now + this->range_duration;
+//			this->expected_tx_end_time = time_now + this->range_duration;
+//
+//
+//        	//add cooldown to prevent polling same tag too rapidly (can block reception of blinks from other tags)
+//        	tx_timing_node *node = malloc(sizeof(tx_timing_node));
+//			node->index = index;
+//			node->duration = this->poll_frequency_period;
+//			node->time = time_now;
+//
+//			this->add_node(this, node);
+//
+//			return index;
+//		}
+//
+//		index = (index + 1)%uwb_list_len;
+//		num_checked++;
+//	}
+
+	return;
+}
+
+
+static bool add_node(struct TDMAHandler *this, tdma_timing_node *node) //TODO handle unsuccessful add
+{
+//	char debug_msg[100];
+//	n = sprintf((char*)&debug_msg[0], "node added, index %i", *node->index);
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
+	if(llist_is_empty(this->list))
+	{
+		return llist_add_node(this->list, node, ADD_NODE_REAR);
+	}
+	else{
+		uint32 offset = 0;
+
+		//force number wrapping in case the timestamp is getting close to wrapping
+		if(node->time > 4000000000){
+			offset = 1000000000;
+		}
+
+		tdma_timing_node *pos_node = llist_get_head(this->list);
+		while(pos_node != NULL){
+
+			if(node->time + offset < pos_node->time + offset){
+				return llist_insert_node(this->list, node, pos_node, ADD_NODE_BEFORE);
+			}
+
+			pos_node = llist_get_next(this->list, node);
+		}
+
+		return llist_add_node(this->list, node, ADD_NODE_REAR);
+	}
+}
+
+static struct TDMAHandler new(instance_data_t *inst){
+	struct TDMAHandler ret = {};
+//	ret.blink_period = (int)(1.0/(int)BLINK_PERIOD_MS);
+//	ret.uwb_list = uwb_list;
+//	ret.uwb_list_length = uwb_list_length;
+//	ret.uwb_max_list_length = uwb_max_list_length;
+//	ret.uwb_timeout_list = uwb_timeout_list; //might need uwbliststate pointer here
+
+	ret.list = llist_create(tdma_node_compare, tdma_node_equal, 0);
+
+	ret.add_node = &add_node;
+	ret.set_slot = &set_slot;
+
+	uint32 time_now = portGetTickCnt();
+
+	ret.last_blink_time = time_now;
+	ret.framelength = MIN_FRAMELENGTH;
+	ret.maxFramelength = min_framelength;
+	while(ret.maxFramelength < ret.uwb_max_list_length + 1)
+	{
+		ret.maxFramelength *= 2;
+	}
+    ret.slotDuration = 30; //TODO use a #define or something?
+
+    ret.slotAssignments = malloc(sizeof(uint16)*ret.maxFramelength);
+    for(int i = 0; i < ret.maxFramelength; i++)
+    {
+    	uint16 blank = 0x0000;
+    	memcpy(&ret.slotAssignments[i], &blank, 2);
+    }
+
+    ret.uwbFramelengths = malloc(sizeof(uint8)*ret.maxFramelength);
+    for(int i = 0; i < 	ret.uwb_max_list_length; i++)
+    {
+    	ret.uwbFramelengths[i] = 0;
+    }
+
+    ret.frameStartTime = time_now;
+    ret.lastSlotStartTime = time_now;
+    ret.discoveryStartTime = time_now;
+    ret.last_blink_time = time_now;
+
+	return ret;
+}
+
+const struct TDMAHandlerClass TDMASHandler={.new=&new};
+
+
diff --git a/src/application/tdma_scheduler.h b/src/application/tdma_scheduler.h
new file mode 100644
index 0000000..37c968b
--- /dev/null
+++ b/src/application/tdma_scheduler.h
@@ -0,0 +1,62 @@
+#ifndef TDMA_HANDLER_H_
+#define TDMA_HANDLER_H_
+
+#include "llist.h"
+#include "deca_types.h"
+#include "instance.h"
+
+typedef struct
+{
+	uint32 time;      			//time the node is scheduled to be used.
+	uint32 duration;            //expected time the node event will take before completion
+	uint8 index;            	//the node index
+
+} tdma_timing_node;
+
+
+struct TDMASHandler
+{
+
+	llist list;					//list of tdma_timing_nodes
+
+	//instance variables
+	instance_data_t *inst;
+//	uint8 uwb_max_list_length;
+//	uint8 *uwb_list_length;
+
+//	uint8 (*uwb_list)[][8];             //pointer to uwbList
+//	uint8 *uwb_timeout_list;          //pointer to uwbTimeout
+	//might need uwbliststate pointer here
+
+
+    //TDMA class variables
+    uint8 framelength;
+	uint8 maxFramelength;
+	uint16 *slotAssignments; //TODO may need two slot assignments!
+	uint8 *uwbFramelengths; //[UWB_LIST_SIZE]
+	uint32 frameStartTime; //TODO how to sync
+	uint32 lastSlotStartTime;
+	uint32 slotDuration;   //TODO 30 ms?
+	uint32 discoveryStartTime; //time that we started listening for other UWBs
+
+	//discovery variables
+//	uint32 blink_period;
+	uint32 last_blink_time;	   //timestamp of most recent blink
+
+
+    //class functions
+	void (*set_slot)(struct TDMAHandler *this);
+    bool (*add_node)(struct TDMAHandler *this, tdma_timing_node *node);
+
+};
+
+
+extern const struct TDMAHandlerClass
+{
+//	struct TDMAScheduler (*new)(float blink_frequency, uint32 blink_duration, uint32 range_duration, uint8 (*uwb_list)[][8], uint8 *uwb_list_length, uint8 uwb_max_list_length, uint8 uwb_timeout_list[]);
+	struct TDMAHandler (*new)(instance_data_t *inst);
+
+} TDMAHandler;
+
+
+#endif
diff --git a/src/application/tx_scheduler.c b/src/application/tx_scheduler.c
index 9ec5cf3..12ad530 100644
--- a/src/application/tx_scheduler.c
+++ b/src/application/tx_scheduler.c
@@ -1,4 +1,4 @@
-#include "tx_scheduler.h"
+#include "tmda_scheduler.h"
 #include "port.h"
 
 
@@ -6,10 +6,10 @@ extern void usb_run(void);
 extern void send_usbmessage(uint8*, int);
 
 //private methods
-int tx_node_compare(llist_node first, llist_node second)
+int tdma_node_compare(llist_node first, llist_node second)
 {
-    tx_timing_node *first_node = (tx_timing_node *)first;
-    tx_timing_node *second_node = (tx_timing_node *)second;
+    tdma_timing_node *first_node = (tx_timing_node *)first;
+    tdma_timing_node *second_node = (tx_timing_node *)second;
 
 	if(first_node->time == second_node->time)
 	{
@@ -27,7 +27,7 @@ int tx_node_compare(llist_node first, llist_node second)
 }
 
 
-bool tx_node_equal(llist_node first, llist_node second)
+bool tdma_node_equal(llist_node first, llist_node second)
 {
     if(first == second){return true;}
 
@@ -36,10 +36,7 @@ bool tx_node_equal(llist_node first, llist_node second)
 
 
 //class methods
-
-//return index of uwb to initiate comms with
-//index 0-244 for uwb, 255 for blink, -1 for none
-static int tx_select(struct TXScheduler *this)
+static int set_slot(struct TDMAScheduler *this)
 {
 	uint32 time_now = portGetTickCnt();
 	uint32 offset = 0;
@@ -65,7 +62,7 @@ static int tx_select(struct TXScheduler *this)
 
 		if(llist_size(this->list) == 0){break;}
 
-		tx_timing_node *node = llist_get_head(this->list);
+		tdma_timing_node *node = llist_get_head(this->list);
 
 		if(time_now_offset > node->time + node->duration + offset){ //expired
 			llist_delete_node(this->list, node, true, NULL);
@@ -133,7 +130,8 @@ static int tx_select(struct TXScheduler *this)
 	return -1;
 }
 
-static bool add_node(struct TXScheduler *this, tx_timing_node *node) //TODO handle unsuccessful add
+
+static bool add_node(struct TDMAScheduler *this, tdma_timing_node *node) //TODO handle unsuccessful add
 {
 //	char debug_msg[100];
 //	n = sprintf((char*)&debug_msg[0], "node added, index %i", *node->index);
@@ -166,23 +164,51 @@ static bool add_node(struct TXScheduler *this, tx_timing_node *node) //TODO hand
 	}
 }
 
-static struct TXScheduler new(float blink_frequency, uint32 blink_duration, uint32 range_duration, uint8 (*uwb_list)[][8], uint8 *uwb_list_length, uint8 uwb_max_list_length, uint8 uwb_timeout_list[]){
-	struct TXScheduler ret = {.uwb_list = uwb_list, .uwb_list_length = uwb_list_length, .uwb_max_list_length=uwb_max_list_length, .uwb_timeout_list = uwb_timeout_list};
-	ret.list = llist_create(tx_node_compare, tx_node_equal, 0);
-	ret.blink_frequency = blink_frequency;
-	ret.blink_duration = blink_duration;
-	ret.range_duration = range_duration;
+static struct TDMAScheduler new(float blink_frequency, uint8 (*uwb_list)[][8], uint8 *uwb_list_length, uint8 uwb_max_list_length, uint8 min_framelength /*uint8 uwb_timeout_list[]*/){
+	struct TDMAScheduler ret = {};
 	ret.blink_period = (int)(1.0/blink_frequency);
-	ret.tx_select = &tx_select;
+	ret.uwb_list = uwb_list;
+	ret.uwb_list_length = uwb_list_length;
+	ret.uwb_max_list_length = uwb_max_list_length;
+//	ret.uwb_timeout_list = uwb_timeout_list; //might need uwbliststate pointer here
+
+	ret.list = llist_create(tx_node_compare, tx_node_equal, 0);
+
 	ret.add_node = &add_node;
-	ret.last_blink_time = 0;
-	ret.last_select_index = 0;
-	ret.time_reject_select = 0;
-	ret.poll_frequency = .05;
-	ret.poll_frequency_period = (uint32)(1.0/ret.poll_frequency);
+	ret.set_slot = &set_slot;
+
+	time_now = portGetTickCnt();
+
+	ret.last_blink_time = time_now;
+	ret.framelength = min_framelength;
+	ret.maxFramelength = min_framelength;
+	while(ret.maxFramelength < ret.uwb_max_list_length + 1)
+	{
+		ret.maxFramelength *= 2;
+	}
+    ret.slotDuration = 30; //TODO use a #define or something?
+
+    ret.slotAssignments = malloc(sizeof(uint16)*ret.maxFramelength);
+    for(int i = 0; i < inst->maxFramelength; i++)
+    {
+    	uint16 blank = 0x0000;
+    	memcpy(&ret.slotAssignments[i], &blank, 2);
+    }
+
+    ret.uwbFramelengths = malloc(sizeof(uint8)*ret.maxFramelength);
+    for(int i = 0; i < 	ret.uwb_max_list_length; i++)
+    {
+    	ret.uwbFramelengths[i] = 0;
+    }
+
+    ret.frameStartTime = time_now;
+    ret.lastSlotStartTime = time_now;
+    ret.discoveryStartTime = time_now;
+    ret.last_blink_time = time_now;
+
 	return ret;
 }
 
-const struct TXSchedulerClass TXScheduler={.new=&new};
+const struct TDMASchedulerClass TDMAScheduler={.new=&new};
 
 
diff --git a/src/application/tx_scheduler.h b/src/application/tx_scheduler.h
index 9d32a3a..2864637 100644
--- a/src/application/tx_scheduler.h
+++ b/src/application/tx_scheduler.h
@@ -1,5 +1,9 @@
+#ifndef TDMA_SCHEDULER_H_
+#define TDMA_SCHEDULER_H_
+
 #include "llist.h"
 #include "deca_types.h"
+#include "instance.h"
 
 typedef struct
 {
@@ -7,49 +11,50 @@ typedef struct
 	uint32 duration;            //expected time the node event will take before completion
 	uint8 index;            	//the node index
 
-} tx_timing_node;
+} tdma_timing_node;
 
 
-struct TXScheduler
+struct TDMAScheduler
 {
 
-	llist list;					//list of tx_timing_nodes
-
-
-
-
+	llist list;					//list of tdma_timing_nodes
 
+	//instance variables
 	uint8 uwb_max_list_length;
 	uint8 *uwb_list_length;
 
 	uint8 (*uwb_list)[][8];             //pointer to uwbList
-	uint8 *uwb_timeout_list;          //pointer to uwbTimeout
+//	uint8 *uwb_timeout_list;          //pointer to uwbTimeout
+	//might need uwbliststate pointer here
 
-	float blink_frequency;
-	uint32 blink_period;
-	uint32 blink_duration;
-	uint32 range_duration;
 
+    //TDMA class variables
+    uint8 framelength;
+	uint8 maxFramelength;
+	uint16 *slotAssignments; //TODO may need two slot assignments!
+	uint8 *uwbFramelengths; //[UWB_LIST_SIZE]
+	uint32 frameStartTime; //TODO how to sync
+	uint32 lastSlotStartTime;
+	uint32 slotDuration;   //TODO 30 ms?
+	uint32 discoveryStartTime; //time that we started listening for other UWBs
 
-	float poll_frequency;
-	uint32 poll_frequency_period;
+	//discovery variables
+	uint32 blink_period;
+	uint32 last_blink_time;	   //timestamp of most recent blink
 
-    uint32 last_blink_time;      //timestamp of most recent blink
-//    uint32 accepted_node_end_time;
-    uint8 last_select_index;     //index of most recently selected uwb
-    uint32 expected_tx_end_time;
-    uint32 time_reject_select;
 
-    int  (*tx_select)(struct TXScheduler *this);
-    bool (*add_node)(struct TXScheduler *this, tx_timing_node *node);
+    //class functions
+	void (*set_slot)(struct TDMAScheduler *this);
+    bool (*add_node)(struct TDMAScheduler *this, tdma_timing_node *node);
 
 };
 
 
-extern const struct TXSchedulerClass
+extern const struct TDMASchedulerClass
 {
-	struct TXScheduler (*new)(float blink_frequency, uint32 blink_duration, uint32 range_duration, uint8 (*uwb_list)[][8], uint8 *uwb_list_length, uint8 uwb_max_list_length, uint8 uwb_timeout_list[]);
+	struct TDMAScheduler (*new)(float blink_frequency, uint32 blink_duration, uint32 range_duration, uint8 (*uwb_list)[][8], uint8 *uwb_list_length, uint8 uwb_max_list_length, uint8 uwb_timeout_list[]);
 
-} TXScheduler;
+} TDMAScheduler;
 
 
+#endif
diff --git a/src/decadriver/deca_device.c b/src/decadriver/deca_device.c
index eb85741..a146ec9 100644
--- a/src/decadriver/deca_device.c
+++ b/src/decadriver/deca_device.c
@@ -2128,9 +2128,17 @@ uint8 dwt_checkirq(void)
  */
 void dwt_isr(void)
 {
+
+
     uint32 status = dw1000local.cbData.status = dwt_read32bitreg(SYS_STATUS_ID); // Read status register low 32bits
-    uint8 status_high = dwt_read8bitoffsetreg(SYS_STATUS_ID, 4);
-    uint32 mask = dwt_read32bitreg(SYS_MASK_ID);
+//    uint8 status_high = dwt_read8bitoffsetreg(SYS_STATUS_ID, 4);
+//    uint32 mask = dwt_read32bitreg(SYS_MASK_ID);
+
+//    uint8 debug_msg[50];
+//	int n = sprintf((char*)&debug_msg[0], "dwt_isr SYS_STATUS: %lu", status);
+//	send_usbmessage(&debug_msg[0], n);
+//	usb_run();
+
 
     uint8 callback_triggered = 0;
 
@@ -2186,7 +2194,7 @@ void dwt_isr(void)
          if (dw1000local.dblbuffon)
          {
              // Toggle the Host side Receive Buffer Pointer
-//             dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET, 1);
+             dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET, 1);
          }
     }
 
@@ -2220,19 +2228,19 @@ void dwt_isr(void)
     {
     	callback_triggered = 1;
 
-    	uint32 and_status = status & SYS_STATUS_ALL_RX_TO;
-		uint8 debug_msg[100];
-		int n = 0;
-		n = sprintf((char*)&debug_msg[0], "rx_timeout!!! and_status: %lu", and_status);
-		send_usbmessage(&debug_msg[0], n);
-		usb_run();
+//    	uint32 and_status = status & SYS_STATUS_ALL_RX_TO;
+//		uint8 debug_msg[100];
+//		int n = 0;
+//		n = sprintf((char*)&debug_msg[0], "rx_timeout!!! and_status: %lu", and_status);
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
 
-		if(and_status & SYS_STATUS_AFFREJ){
-			uint32 sys_cfg_reg = dwt_read32bitreg(SYS_CFG_ID);
-			n = sprintf((char*)&debug_msg[0], "rx_timeout!!! sys_cfg_reg: %lu", sys_cfg_reg);
-			send_usbmessage(&debug_msg[0], n);
-			usb_run();
-		}
+//		if(and_status & SYS_STATUS_AFFREJ){
+//			uint32 sys_cfg_reg = dwt_read32bitreg(SYS_CFG_ID);
+//			n = sprintf((char*)&debug_msg[0], "rx_timeout!!! sys_cfg_reg: %lu", sys_cfg_reg);
+//			send_usbmessage(&debug_msg[0], n);
+//			usb_run();
+//		}
 
 
 
@@ -2258,17 +2266,17 @@ void dwt_isr(void)
     {
     	callback_triggered = 1;
 
-    	uint32 and_status = status & SYS_STATUS_ALL_RX_ERR;
-		uint8 debug_msg[100];
-		int n = 0;
-		n = sprintf((char*)&debug_msg[0], "rx_error!!! and_status: %lu", and_status);
-		send_usbmessage(&debug_msg[0], n);
-		usb_run();
-
-		n = sprintf((char*)&debug_msg[0], "rx_error!!! sys_status: %lu", status);
-		send_usbmessage(&debug_msg[0], n);
-		usb_run();
-
+//    	uint32 and_status = status & SYS_STATUS_ALL_RX_ERR;
+//		uint8 debug_msg[100];
+//		int n = 0;
+//		n = sprintf((char*)&debug_msg[0], "rx_error!!! and_status: %lu", and_status);
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
+//
+//		n = sprintf((char*)&debug_msg[0], "rx_error!!! sys_status: %lu", status);
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
+//
 //		if(and_status & SYS_STATUS_AFFREJ){
 //			uint32 sys_cfg_reg = dwt_read32bitreg(SYS_CFG_ID);
 //			n = sprintf((char*)&debug_msg[0], "rx_error!!! sys_cfg_reg: %lu", sys_cfg_reg);
@@ -2300,10 +2308,10 @@ void dwt_isr(void)
     	uint32 SYS_STATUS_ALL_INT = 1073217534; //TODO cleanup
     	dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_INT);
 
-    	uint8 debug_msg[50];
-		int n = sprintf((char*)&debug_msg[0], "unsubscribed callback");
-		send_usbmessage(&debug_msg[0], n);
-		usb_run();
+//    	uint8 debug_msg[50];
+//		int n = sprintf((char*)&debug_msg[0], "unsubscribed callback");
+//		send_usbmessage(&debug_msg[0], n);
+//		usb_run();
 
     }
 
@@ -2712,23 +2720,23 @@ void dwt_forcetrxoff(void)
     uint32 new_mask = dwt_read32bitreg(SYS_MASK_ID);
     new_mask &= SYS_MASK_VAL;
 
-    uint8 mismatch = 0;
+//    uint8 mismatch = 0;
 
 //    while(new_mask != SYS_MASK_VAL){
-	if(new_mask != SYS_MASK_VAL){
-//		dwt_write32bitreg(SYS_MASK_ID, mask);
-//		new_mask = dwt_read32bitreg(SYS_MASK_ID);
-//		new_mask &= SYS_MASK_VAL;
-
-		mismatch = 1;
-    }
+//	if(new_mask != SYS_MASK_VAL){
+////		dwt_write32bitreg(SYS_MASK_ID, mask);
+////		new_mask = dwt_read32bitreg(SYS_MASK_ID);
+////		new_mask &= SYS_MASK_VAL;
+//
+//		mismatch = 1;
+//    }
 
-    if(mismatch == 1){
-		 uint8 debug_msg[100];
-		 int n = sprintf((char*)&debug_msg[0], "mismatch occurred!");
-		 send_usbmessage(&debug_msg[0], n);
-		 usb_run();
-    }
+//    if(mismatch == 1){
+//		 uint8 debug_msg[100];
+//		 int n = sprintf((char*)&debug_msg[0], "mismatch occurred!");
+//		 send_usbmessage(&debug_msg[0], n);
+//		 usb_run();
+//    }
 
 //    if(new_mask != mask){
 //    	uint8 mismatch = 1;
diff --git a/src/liblist/inc/llist.h b/src/liblist/inc/llist.h
deleted file mode 100644
index f5163b0..0000000
--- a/src/liblist/inc/llist.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- *    Copyright [2013] [Ramon Fried] <ramon.fried at gmail dot com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef LLIST_H_
-#define LLIST_H_
-
-#include <stdbool.h>
-
-/*
- * E_LLIST
- * This is the return values most of the llist API return,
- * don't forget to check for success :)
- */
-typedef enum {
-	LLIST_SUCCESS = 0x00,		/**< Operating success */
-	LLIST_NODE_NOT_FOUND,		/**< Error: No matching node found*/
-	LLIST_EQUAL_MISSING,		/**< Error: Equal function is missing*/
-	LLIST_COMPERATOR_MISSING,	/**< Error: Comparator function is missing*/
-	LLIST_NULL_ARGUMENT,		/**< Error: NULL argument*/
-	LLIST_MALLOC_ERROR,		/**< Error: Memory allocation error*/
-	LLIST_NOT_IMPLEMENTED,          /**< Error: Implementation missing*/
-	LLIST_MULTITHREAD_ISSUE,        /**< Error: Multithreading issue*/
-	LLIST_ERROR			/**< Error: Generic error*/
-} E_LLIST;
-
-#define ADD_NODE_FRONT		(1 << 0)
-#define ADD_NODE_REAR		~ADD_NODE_FRONT
-
-#define ADD_NODE_BEFORE    (1 << 0)
-#define ADD_NODE_AFTER      ~ADD_NODE_BEFORE
-
-#define SORT_LIST_ASCENDING (1 << 0)
-#define SORT_LIST_DESCENDING ~SORT_LIST_ASCENDING
-
-#define FLAG_MT_SUPPORT  (1 << 0)
-
-typedef void *llist;
-typedef void *llist_node;
-
-// function prototypes
-typedef void (*node_func)(llist_node node);
-
-// function prototypes with user arguments
-typedef void (*node_func_arg)(llist_node node, void *arg);
-
-/**
-* @brief Compares two nodes in a list
-* @param[in] first llist_node
-* @param[in] second llist_node
-* @return an integer less than, equal to, or greater than zero if first,
-* respectively, to be less than, to match, or be greater than second.
-*/
-typedef int (*comperator)(llist_node first, llist_node second);
-
-/**
-* @brief Check if two nodes are equal
-* @param[in] first llist_node
-* @param[in] second llist_node
-* @return true if the nodes are equal, false otherwise
-*/
-typedef bool (*equal)(llist_node, llist_node);
-
-#define LLIST_INITALIZER {0, NULL, NULL, NULL, NULL}
-
-/**
- * @brief Create a list
- * @param[in] compare_func a function used to compare elements in the list
- * @param[in] equal_func a function used to check if two elements are equal
- * @param[in] flags used to identify whether we create a thread safe linked-list
- * @return new list if success, NULL on error
- */
-llist llist_create(comperator compare_func, equal equal_func,
-		   unsigned int flags);
-
-/**
- * @brief Destroys a list
- * @warning Call this function only if the list was created with llist_create
- *          Static initializer created list cannot be destroyed using this function
- * @param[in] list The list to destroy
- * @param[in] destroy_nodes true if the nodes should be destroyed, false if not
- * @param[in] destructor alternative destructor, if the previous param is true,
- *			  if NULL is provided standard library c free() will be used
- */
-void llist_destroy(llist list, bool destroy_nodes, node_func destructor);
-
-/**
- * @brief Add a node to a list
- * @param[in] list the list to operator upon
- * @param[in] node the node to add
- * @param[in] flags flags
- * @return int LLIST_SUCCESS if success
- */
-int llist_add_node(llist list, llist_node node, int flags);
-
-/**
- * @brief Insert a node at a specific location
- * @param[in] list the list to operator upon
- * @param[in] new_node the node to add
- * @param[in] pos_node a position reference node
- * @param[in] flags flags
- * @return int LLIST_SUCCESS if success
- */
-int llist_insert_node(llist list,  llist_node new_node, llist_node pos_node,
-		      int flags);
-
-/**
- * @brief Delete a node from a list
- * @param[in] list the list to operator upon
- * @param[in] node the node to delete
- * @param[in] destroy_node Should we run a destructor
- * @param[in] destructor function, if NULL is provided, free() will be used
- * @return int LLIST_SUCCESS if success
- */
-int llist_delete_node(llist list, llist_node node, bool destroy_node,
-		      node_func destructor);
-
-/**
- * @brief Finds a node in a list
- * @param[in]  list the list to operator upon
- * @param[in]  data the data to find
- * @param[out] found a pointer for found node.
- *		this pointer can be used only if
- *		llist_find_node returned LLIST_SUCCESS
- * @return LLIST_SUCCESS if success
- */
-int llist_find_node(llist list, void *data, llist_node *found);
-
-/**
- * @brief operate on each element of the list
- * @param[in] list the list to operator upon
- * @param[in] func the function to perform
- * @return int LLIST_SUCCESS if success
- */
-int llist_for_each(llist list, node_func func);
-
-/**
- * @brief operate on each element of the list
- * @param[in] list the list to operator upon
- * @param[in] func the function to perform
- * @param[in] arg passed to func
- * @return int LLIST_SUCCESS if success
- */
-int llist_for_each_arg(llist list, node_func_arg func, void *arg);
-/**
- * @brief sort a lists
- * @param[in] list the list to operator upon
- * @param[in] flags
- * @return int LLIST_SUCCESS if success
- */
-int llist_sort(llist list, int flags);
-
-/**
- * @brief Returns the head node of the list
- * @param[in] list the list to operate on
- * @return the head node, NULL on error
- */
-llist_node llist_get_head(llist list);
-
-/**
- * @brief Returns the next node of the list
- * @param[in] list the list to operate on
- * @param[in] node the node to start from 
- * @return the next node, NULL on error
- */
-llist_node llist_get_next(llist list, llist_node node);
-
-/**
- * @brief Returns the tail node of the list
- * @param[in] list the list to operate on
- * @return the tail node, NULL on error
- */
-llist_node llist_get_tail(llist list);
-
-/**
- * @brief push a node to the head of the list
- * @param[in] list the list to operate on
- * @param[in] node the node to push
- * @return int LLIST_SUCCESS if success
- */
-int llist_push(llist list, llist_node node);
-
-/**
- * @brief peek at the head of the list
- * @param[in] list the list to operate on
- * @return llist_node the head node
- */
-llist_node llist_peek(llist list);
-
-/**
- * @brief pop the head of the list
- * @param[in] list the list to operate on
- * @return llist_node the head node
- */
-llist_node llist_pop(llist list);
-
-/**
- * @brief return the number of elements in the list
- * @param[in] list the list to operate on
- * @return int  number of elements in the list or -1 if error
- */
-int llist_size(llist list);
-
-/**
- * @brief concatenate the second list to the first list
- * @param[in] first the list to operate on
- * @param[in] second the list to operate on.
- * @warning The nodes from the second list will be deleted and concatenated to the first list
- *          Remember to call llist_destroy() on  the second list (if it was created by llist_create())
- * @return int LLIST_SUCCESS if success
- */
-int llist_concat(llist first, llist second);
-
-/**
- * @brief merge the second list to the first list
- * @param[in] first the list to operate on
- * @param[in] second the list to operate on
- * @warning The nodes from the second list will be deleted and merged to the first list
- *          Remember to call llist_destroy() on  the second list (if it was created by llist_create())
- * @return int LLIST_SUCCESS if success
- */
-int llist_merge(llist first, llist second);
-
-/**
- * @brief get the maximum node in a given list
- * @param[in] list the list to operate upon
- * @param[out] max maximum node
- * @return int LLIST_SUCCESS if success
- */
-int llist_get_max(llist list, llist_node *max);
-
-/**
- * @brief get the minimum node in a given list
- * @param[in] list the list to operate upon
- * @param[out] min minumum node
- * @return int LLIST_SUCCESS if success
- */
-int llist_get_min(llist list, llist_node *min);
-
-/**
- * @brief Reverse a list
- * @param[in] list the list to operate upon
- * @return int LLIST_SUCCESS if success
- */
-int llist_reverse(llist list);
-
-/**
- * @brief check if list is empty
- * @param[in] list the list to operate upon
- * @return bool True if list is empty
- */
-bool llist_is_empty(llist list);
-
-#endif /* LLIST_H_ */
diff --git a/src/liblist/src/Complex.c b/src/liblist/src/Complex.c
deleted file mode 100644
index 45bbec4..0000000
--- a/src/liblist/src/Complex.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "Complex.h"
-
-static double abss(struct Complex *this) {
-	return this->re*this->re+this->im*this->im;
-}
-static struct Complex new(double real, double imag) {
-	return (struct Complex){.re=real, .im=imag, .abss=&abss};
-}
-const struct ComplexClass Complex={.new=&new};
diff --git a/src/liblist/src/Complex.h b/src/liblist/src/Complex.h
deleted file mode 100644
index 802285d..0000000
--- a/src/liblist/src/Complex.h
+++ /dev/null
@@ -1,7 +0,0 @@
-struct Complex {
-	double re, im;
-	double (*abss)(struct Complex *this);
-};
-extern const struct ComplexClass {
-	struct Complex (*new)(double real, double imag);
-} Complex;
diff --git a/src/liblist/src/llist.c b/src/liblist/src/llist.c
deleted file mode 100644
index fd2382f..0000000
--- a/src/liblist/src/llist.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- *    Copyright [2013] [Ramon Fried] <ramon.fried at gmail dot com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include "../inc/llist.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <pthread.h>
-
-#define LOG_FUNC_ENTRANCE() printf("%lu: In %s\n", time(NULL), __PRETTY_FUNCTION__);
-
-typedef struct __list_node {
-	llist_node node;
-	struct __list_node *next;
-} _list_node;
-
-typedef struct {
-	unsigned int count;
-	comperator comp_func;
-	equal equal_func;
-	_list_node *head;
-	_list_node *tail;
-
-} _llist;
-
-
-/* Helper functions - not to be exported */
-static _list_node *listsort(_list_node *list, _list_node **updated_tail,
-			    comperator cmp, int flags);
-
-llist llist_create(comperator compare_func, equal equal_func, unsigned int flags)
-{
-	_llist *new_list;
-//	int rc = 0;
-
-	new_list = malloc(sizeof(_llist));
-
-	if (new_list == NULL)
-		return NULL;
-
-// These can be NULL, I don't care...
-	new_list->equal_func = equal_func;
-	new_list->comp_func = compare_func;
-
-// Reset the list
-	new_list->count = 0;
-	new_list->head = NULL;
-	new_list->tail = NULL;
-
-	return new_list;
-}
-
-void llist_destroy(llist list, bool destroy_nodes, node_func destructor)
-{
-	_list_node *iterator;
-	_list_node *next;
-
-	if (list == NULL)
-		return;
-
-	// Delete the data contained in the nodes
-	iterator = ((_llist *) list)->head;
-
-	while (iterator != NULL) {
-
-		if (destroy_nodes) {
-			if (destructor)
-				destructor(iterator->node);
-			else
-				free(iterator->node);
-		}
-
-		next = iterator->next;
-		free(iterator);    // Delete's the container
-		iterator = next;
-	}
-
-	//release the list
-	free(list);
-}
-
-int llist_size(llist list)
-{
-	if (list == NULL)
-		return 0;
-
-	//read only critical section
-	unsigned int retval = ((_llist *) list)->count;
-
-	return retval;
-}
-
-int llist_add_node(llist list, llist_node node, int flags)
-{
-
-	if (list == NULL)
-		return LLIST_NULL_ARGUMENT;
-
-	_list_node *node_wrapper = NULL;
-
-	node_wrapper = malloc(sizeof(_list_node));
-	if (node_wrapper == NULL)
-		return LLIST_MALLOC_ERROR;
-
-	node_wrapper->node = node;
-	((_llist *) list)->count++;
-
-	if (((_llist *) list)->head == NULL) {      // Adding the first node, update head and tail to point to that node
-		node_wrapper->next = NULL;
-		((_llist *) list)->head =
-			((_llist *) list)->tail = node_wrapper;
-	} else if (flags & ADD_NODE_FRONT) {
-		node_wrapper->next = ((_llist *) list)->head;
-		((_llist *) list)->head = node_wrapper;
-	} else { // add node in the rear
-		node_wrapper->next = NULL;
-		((_llist *) list)->tail->next = node_wrapper;
-		((_llist *) list)->tail = node_wrapper;
-	}
-
-
-	return LLIST_SUCCESS;
-}
-
-int llist_delete_node(llist list, llist_node node,
-		      bool destroy_node, node_func destructor)
-{
-	_list_node *iterator;
-	_list_node *tail;
-	_list_node *temp;
-	equal actual_equal;
-
-	if ((list == NULL) || (node == NULL))
-		return LLIST_NULL_ARGUMENT;
-
-	actual_equal = ((_llist *) list)->equal_func;
-
-	if (actual_equal == NULL)
-		return LLIST_EQUAL_MISSING;
-
-	iterator = ((_llist *) list)->head;
-	tail = ((_llist *) list)->tail;
-
-
-	if (iterator == NULL) {
-		return LLIST_NODE_NOT_FOUND;
-	}
-
-	// is it the first node ?
-	if (actual_equal(iterator->node, node)) {
-		if (destroy_node) {
-			if (destructor)
-				destructor(iterator->node);
-			else
-				free(iterator->node);
-		}
-
-		((_llist *) list)->head = ((_llist *) list)->head->next;
-		free(iterator);
-		((_llist *) list)->count--;
-
-		if (((_llist *) list)->count == 0) {
-			/*
-			 *  if we deleted the last node, we need to reset the tail also
-			 *  There's no need to check it somewhere else, because the last node must be the head (and tail)
-			 */
-			((_llist *) list)->tail = NULL;
-			((_llist *) list)->head = NULL;
-		}
-		//assert ( ( ( _llist * ) list )->count >= 0 );
-		return LLIST_SUCCESS;
-	}else if(actual_equal(tail->node, node)){ //is it the last node?
-		while(iterator->next != tail){
-			iterator = iterator->next;
-		}
-		//iterator now second to last.
-		((_llist *) list)->tail = iterator;
-		iterator->next = NULL;
-		if (destroy_node) {
-			if (destructor)
-				destructor(tail->node);
-			else
-				free(tail->node);
-		}
-
-		free(tail);
-		((_llist *) list)->count--;
-
-		return LLIST_SUCCESS;
-	} else {
-		while (iterator->next != NULL) {
-			if (actual_equal(iterator->next->node, node)) {
-				// found it
-				temp = iterator->next;
-				iterator->next = temp->next;
-				if (destroy_node) {
-					if (destructor)
-						destructor(temp->node);
-					else
-						free(temp->node);
-				}
-				free(temp);
-
-				((_llist *) list)->count--;
-				//assert ( ( ( _llist * ) list )->count >= 0 );
-
-				return LLIST_SUCCESS;
-			}
-
-			iterator = iterator->next;
-
-		}
-	}
-
-	if (iterator->next == NULL) {
-		return LLIST_NODE_NOT_FOUND;
-	}
-
-	//assert ( 1 == 2 );
-	// this assert always failed. we assume that the function never gets here...
-
-	return LLIST_ERROR;
-}
-
-int llist_for_each(llist list, node_func func)
-{
-	_list_node *iterator;
-
-	if ((list == NULL) || (func == NULL))
-		return LLIST_NULL_ARGUMENT;
-
-	iterator = ((_llist *) list)->head;
-
-	while (iterator != NULL) {
-		func(iterator->node);
-		iterator = iterator->next;
-	}
-
-	return LLIST_SUCCESS;
-}
-
-int llist_for_each_arg(llist list, node_func_arg func, void *arg)
-{
-	_list_node *iterator;
-
-	if ((list == NULL) || (func == NULL))
-		return LLIST_NULL_ARGUMENT;
-
-	iterator = ((_llist *) list)->head;
-
-	while (iterator != NULL) {
-		func(iterator->node, arg);
-		iterator = iterator->next;
-	}
-
-	return LLIST_SUCCESS;
-}
-
-int llist_insert_node(llist list, llist_node new_node, llist_node pos_node,
-		      int flags)
-{
-	_list_node *iterator;
-	_list_node *node_wrapper = NULL;
-
-	if ((list == NULL) || (new_node == NULL) || (pos_node == NULL))
-		return LLIST_NULL_ARGUMENT;
-
-	node_wrapper = malloc(sizeof(_list_node));
-
-	if (node_wrapper == NULL) {
-		return LLIST_MALLOC_ERROR;
-	}
-
-	node_wrapper->node = new_node;
-
-	((_llist *) list)->count++;
-
-	iterator = ((_llist *) list)->head;
-
-	if (iterator->node == pos_node) {
-		// it's the first node
-
-		if (flags & ADD_NODE_BEFORE) {
-			node_wrapper->next = iterator;
-			((_llist *) list)->head = node_wrapper;
-		} else {
-			node_wrapper->next = iterator->next;
-			iterator->next = node_wrapper;
-		}
-
-		//TODO update tail?
-
-		return LLIST_SUCCESS;
-	}
-
-	while (iterator->next != NULL) {
-		if (iterator->next->node == pos_node) {
-			if (flags & ADD_NODE_BEFORE) {
-				node_wrapper->next = iterator->next;
-				iterator->next = node_wrapper;
-			} else {
-				iterator = iterator->next;
-				// now we stand on the pos node
-				node_wrapper->next = iterator->next;
-				iterator->next = node_wrapper;
-			}
-			return LLIST_SUCCESS;
-		}
-
-		iterator = iterator->next;
-	}
-
-
-//	assert(1 == 2);
-	// this assert will always fail. we assume that the function never gets here...
-	return LLIST_ERROR;
-
-}
-
-int llist_find_node(llist list, void *data, llist_node *found)
-{
-	_list_node *iterator;
-	equal actual_equal;
-
-	if (list == NULL)
-		return LLIST_NULL_ARGUMENT;
-
-	actual_equal = ((_llist *) list)->equal_func;
-
-	if (actual_equal == NULL) {
-		return LLIST_EQUAL_MISSING;
-	}
-
-//	read_lock(list);
-
-	iterator = ((_llist *) list)->head;
-	while (iterator != NULL) {
-		if (actual_equal(iterator->node, data)) {
-			*found = iterator->node;
-//			unlock(list);
-			return LLIST_SUCCESS;
-		}
-		iterator = iterator->next;
-	}
-
-//	unlock(list);
-
-	// Didn't find the node
-	return LLIST_NODE_NOT_FOUND;
-}
-
-llist_node llist_get_head(llist list)
-{
-
-	if (list != NULL) {
-		if (((_llist *) list)->head) {      // there's at least one node
-			return ((_llist *) list)->head->node;
-		}
-	}
-
-	return NULL;
-}
-
- llist_node llist_get_next(llist list, llist_node node)
- {
- 	_list_node *iterator;
- 	equal actual_equal;
-
-	if ((list == NULL) || (node == NULL))
-		return NULL;
-
-	iterator = ((_llist *) list)->head;
-	actual_equal = ((_llist *) list)->equal_func;
-
-	if (actual_equal == NULL)
-		return NULL;
-
- 	while(iterator->next != NULL)
- 	{
-		if (actual_equal(iterator->node, node)) {
-			return iterator->next->node;
-		}
-
-		iterator = iterator->next;
- 	}
-
- 	return NULL;
- }
-
-llist_node llist_get_tail(llist list)
-{
-	if (list != NULL)
-		return NULL;
-
-	if (((_llist *) list)->tail) {      // there's at least one node
-		return ((_llist *) list)->tail->node;
-	}
-
-	return NULL;
-}
-
-int llist_push(llist list, llist_node node)
-{
-	return llist_add_node(list, node, ADD_NODE_FRONT);
-}
-
-llist_node llist_peek(llist list)
-{
-	return llist_get_head(list);
-}
-
-llist_node llist_pop(llist list)
-{
-	llist_node tempnode = NULL;
-	_list_node *tempwrapper;
-
-//	write_lock(list);
-
-	if (((_llist *) list)->count) {      // There exists at least one node
-		tempwrapper = ((_llist *) list)->head;
-		tempnode = tempwrapper->node;
-		((_llist *) list)->head = ((_llist *) list)->head->next;
-		((_llist *) list)->count--;
-		free(tempwrapper);
-
-		if (((_llist *) list)->count == 0)      // We've deleted the last node
-			((_llist *) list)->tail = NULL;
-	}
-
-//	unlock(list);
-
-	return tempnode;
-}
-
-int llist_concat(llist first, llist second)
-{
-	_list_node *end_node;
-
-	if ((first == NULL) || (second == NULL))
-		return LLIST_NULL_ARGUMENT;
-
-//	write_lock(first);
-//	write_lock(second);
-
-	end_node = ((_llist *) first)->tail;
-
-	((_llist *) first)->count += ((_llist *) second)->count;
-
-	if (end_node != NULL) {  // if the first list is not empty
-		end_node->next = ((_llist *) second)->head;
-	} else { // It's empty
-		((_llist *) first)->head = ((_llist *) first)->tail =
-					       ((_llist *) second)->head;
-	}
-
-	// Delete the nodes from the second list. (not really deletes them, only loses their reference.
-	((_llist *) second)->count = 0;
-	((_llist *) second)->head = ((_llist *) second)->tail = NULL;
-
-//	unlock(first);
-//	unlock(second);
-
-	return LLIST_SUCCESS;
-}
-
-int llist_reverse(llist list)
-{
-	if (list == NULL)
-		return LLIST_NULL_ARGUMENT;
-
-//	write_lock(list);
-
-	_list_node *iterator = ((_llist *) list)->head;
-	_list_node *nextnode = NULL;
-	_list_node *temp = NULL;
-
-	/*
-	 * Swap our Head & Tail pointers
-	 */
-	((_llist *) list)->head = ((_llist *) list)->tail;
-	((_llist *) list)->tail = iterator;
-
-	/*
-	 * Swap the internals
-	 */
-	while (iterator) {
-		nextnode = iterator->next;
-		iterator->next = temp;
-		temp = iterator;
-		iterator = nextnode;
-	}
-
-//	unlock(list);
-
-	return LLIST_SUCCESS;
-}
-
-int llist_sort(llist list, int flags)
-{
-
-	comperator cmp;
-
-	if (list == NULL)
-		return LLIST_NULL_ARGUMENT;
-
-	_llist *thelist = (_llist *) list;
-
-	cmp =  thelist->comp_func;
-	if (cmp == NULL)
-		return LLIST_COMPERATOR_MISSING;
-
-//	write_lock(list);
-	thelist->head = listsort(thelist->head, &thelist->tail, cmp, flags);
-//	unlock(list);
-	/*
-	 * TODO: update list tail.
-	 */
-	return LLIST_SUCCESS;
-}
-
-static _list_node *listsort(_list_node *list, _list_node **updated_tail,
-			    comperator cmp, int flags)
-{
-	_list_node *p, *q, *e, *tail;
-	int insize, nmerges, psize, qsize, i;
-	int direction = (flags & SORT_LIST_ASCENDING) ? 1 : -1;
-
-	insize = 1;
-
-	while (1) {
-		p = list;
-		list = NULL;
-		tail = NULL;
-
-		nmerges = 0; /* count number of merges we do in this pass */
-
-		while (p) {
-			nmerges++; /* there exists a merge to be done */
-			/* step `insize' places along from p */
-			q = p;
-			psize = 0;
-			for (i = 0; i < insize; i++) {
-				psize++;
-				q = q->next;
-				if (!q) {
-					break;
-				}
-			}
-
-			/* if q hasn't fallen off end, we have two lists to merge */
-			qsize = insize;
-
-			/* now we have two lists; merge them */
-			while (psize > 0 || (qsize > 0 && q)) {
-
-				/* decide whether next element of merge comes from p or q */
-				if (psize == 0) {
-					/* p is empty; e must come from q. */
-					e = q;
-					q = q->next;
-					qsize--;
-				} else if (qsize == 0 || !q) {
-					/* q is empty; e must come from p. */
-					e = p;
-					p = p->next;
-					psize--;
-				} else if ((direction * cmp(p->node, q->node)) <= 0) {
-					/* First element of p is lower (or same);
-					 * e must come from p. */
-					e = p;
-					p = p->next;
-					psize--;
-				} else {
-					/* First element of q is lower; e must come from q. */
-					e = q;
-					q = q->next;
-					qsize--;
-				}
-
-				/* add the next element to the merged list */
-				if (tail) {
-					tail->next = e;
-				} else {
-					list = e;
-				}
-
-				tail = e;
-			}
-
-			/* now p has stepped `insize' places along, and q has too */
-			p = q;
-		}
-
-		tail->next = NULL;
-
-		/* If we have done only one merge, we're finished. */
-		if (nmerges <= 1) {  /* allow for nmerges==0, the empty list case */
-			break;
-		}
-		/* Otherwise repeat, merging lists twice the size */
-		insize *= 2;
-	}
-
-	*updated_tail = tail;
-	return list;
-}
-
-static int llist_get_min_max(llist list, llist_node *output, bool max)
-{
-	comperator cmp;
-
-	if (list == NULL)
-		return LLIST_NULL_ARGUMENT;
-
-	cmp = ((_llist *) list)->comp_func;
-
-	if (cmp == NULL)
-		return LLIST_COMPERATOR_MISSING;
-
-	_list_node *iterator = ((_llist *) list)->head;
-	*output = iterator->node;
-	iterator = iterator->next;
-	while (iterator) {
-		if (max) { // Find maximum
-			if (cmp(iterator->node, *output) > 0) {
-				*output = iterator->node;
-			}
-		} else { // Find minimum
-			if (cmp(iterator->node, *output) < 0) {
-				*output = iterator->node;
-			}
-		}
-		iterator = iterator->next;
-	}
-
-	return LLIST_SUCCESS;
-}
-
-int llist_get_max(llist list, llist_node *max)
-{
-	return llist_get_min_max(list, max, true);
-}
-
-int llist_get_min(llist list, llist_node *min)
-{
-	return llist_get_min_max(list, min, false);
-}
-
-bool llist_is_empty(llist list)
-{
-	return (!llist_size(list));
-}
-
-/*
- * TODO: Implement the below functions
- */
-
-int llist_merge(llist first, llist second)
-{
-	assert(1 == 0);  // Fail, function not implemented yet.
-	return LLIST_NOT_IMPLEMENTED;
-}
diff --git a/src/usb/deca_usb.c b/src/usb/deca_usb.c
index efb9c48..7c082fc 100644
--- a/src/usb/deca_usb.c
+++ b/src/usb/deca_usb.c
@@ -57,7 +57,7 @@ int local_have_data = 0;
 int version_size;
 uint8* version;
 int s1configswitch;
-extern int ranging;
+//extern int ranging;
 
 extern uint32_t APP_Rx_length;
 extern uint32 inittestapplication(uint8 s1switch);
@@ -383,7 +383,7 @@ int process_usbmessage(void)
 					//enable DW1000 IRQ
 					port_EnableEXT_IRQ(); //enable IRQ before starting
 
-					ranging = 0;
+//					ranging = 0;
 
 				}
 				//d (from "deca")
-- 
GitLab