From d550de4367bae1e3c65e262f1db7693ab1c42148 Mon Sep 17 00:00:00 2001
From: Eric Middleton <ericm@iastate.edu>
Date: Fri, 28 Apr 2017 15:25:31 -0500
Subject: [PATCH] Added code for ESP8266 WiFi bridge

---
 controls/DataAnalysisTool/Tool/simplePlots.m  |   6 +-
 controls/model/modelParameters.m              |   2 +-
 groundStation/Makefile                        |   4 +-
 .../ESP8266_Wifi-Serial-Adapter/Makefile      | 140 +++++
 .../ESP8266_Wifi-Serial-Adapter/README.md     |   1 +
 .../driver/RingBuffer.c                       |  48 ++
 .../ESP8266_Wifi-Serial-Adapter/driver/uart.c | 521 ++++++++++++++++++
 .../include/driver/RingBuffer.h               |  21 +
 .../include/driver/uart.h                     | 219 ++++++++
 .../include/driver/uart_register.h            | 156 ++++++
 .../include/espmissingincludes.h              |  78 +++
 .../include/user_config.h                     |   0
 .../include/user_tcp.h                        |  13 +
 .../ESP8266_Wifi-Serial-Adapter/temp/uart.c   | 443 +++++++++++++++
 .../ESP8266_Wifi-Serial-Adapter/temp/uart.h   | 208 +++++++
 .../temp/uart_register.h                      | 156 ++++++
 .../temp/user_main.c                          | 452 +++++++++++++++
 .../user/user_main.c                          | 275 +++++++++
 .../user/user_tcp.c                           | 301 ++++++++++
 19 files changed, 3038 insertions(+), 6 deletions(-)
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/Makefile
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/README.md
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/RingBuffer.c
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/uart.c
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/RingBuffer.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart_register.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/espmissingincludes.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/user_config.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/user_tcp.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.c
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart_register.h
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/user_main.c
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_main.c
 create mode 100644 wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_tcp.c

diff --git a/controls/DataAnalysisTool/Tool/simplePlots.m b/controls/DataAnalysisTool/Tool/simplePlots.m
index 225fb3ce6..bbd8e691d 100644
--- a/controls/DataAnalysisTool/Tool/simplePlots.m
+++ b/controls/DataAnalysisTool/Tool/simplePlots.m
@@ -230,8 +230,8 @@ linkaxes([ax1, ax2, ax3], 'x');
 figure;
 plot(expData.Time.data, expData.Lidar_Constant.data); hold on;
 plot(expData.Time.data, expData.VRPN_Alt_Constant.data);
-
-%angle = sqrt(expData.Roll_Constant.data.^2 + expData.VRPN_Pitch_Constant.data.^2);
+ex
+%angle = sqrt(expData.Roll_Cclearclearonstant.data.^2 + expData.VRPN_Pitch_Constant.data.^2);
 %corrected = expData.Lidar_Constant.data .* cos(angle);
 %plot(expData.Time.data, corrected);
 legend('lidar', 'vrpn');
@@ -411,4 +411,4 @@ for n = 2:length(mag)
     else
         count = 0;
     end
-end
+end
diff --git a/controls/model/modelParameters.m b/controls/model/modelParameters.m
index 9a0694366..beb643488 100644
--- a/controls/model/modelParameters.m
+++ b/controls/model/modelParameters.m
@@ -3,7 +3,7 @@
     addpath(path);
 
 % Log Analysis Toggle
-    logAnalysisToggle = 0;          % 1 for log analysis, 0 for normal operation
+    logAnalysisToggle = 1;          % 1 for log analysis, 0 for normal operation
    
 % Physics Verification Toggle
     physicsVerificationToggle = 1;
diff --git a/groundStation/Makefile b/groundStation/Makefile
index 426a90aa1..c59f815d2 100644
--- a/groundStation/Makefile
+++ b/groundStation/Makefile
@@ -3,8 +3,8 @@
 # Generic Variables
 GCC=gcc
 GXX=g++
-CFLAGS= -Wall -pedantic -Wextra -Werror -std=gnu99 -g -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-but-set-variable
-CXXFLAGS= -Wall -pedantic -Wextra -Werror -Wno-reorder -Wno-unused-variable -std=c++0x -g
+CFLAGS= -Wall -pedantic -Wextra -std=gnu99 -g -Wno-unused-parameter -Wno-unused-variable -Wno-unused-function -Wno-unused-but-set-variable
+CXXFLAGS= -Wall -pedantic -Wextra -Wno-reorder -Wno-unused-variable -std=c++0x -g
 INCLUDES = $(foreach dir, $(INCDIR), -I$(dir))
 INCDIR= src/vrpn src/vrpn/quat src/vrpn/build $(BESRCDIR) $(CLISRCDIR) $(FESRCDIR) ../quad/inc 
 LIBS= -lpthread -lbluetooth -lvrpn -lquat -Lsrc/vrpn/build -Lsrc/vrpn/build/quat -L../quad/lib -lquad_app -lcommands -lgraph_blocks -lcomputation_graph -lm
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/Makefile b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/Makefile
new file mode 100644
index 000000000..1dcb34068
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/Makefile
@@ -0,0 +1,140 @@
+# Makefile for ESP8266 projects
+#
+# Thanks to:
+# - zarya
+# - Jeroen Domburg (Sprite_tm)
+# - Christian Klippel (mamalala)
+# - Tommie Gannert (tommie)
+#
+# Changelog:
+# - 2014-10-06: Changed the variables to include the header file directory
+# - 2014-10-06: Added global var for the Xtensa tool root
+# - 2014-11-23: Updated for SDK 0.9.3
+# - 2014-12-25: Replaced esptool by esptool.py
+
+# Output directors to store intermediate compiled files
+# relative to the project directory
+BUILD_BASE	= build
+FW_BASE		= firmware
+
+# base directory for the compiler
+# NOTE: Replace this with the path to your esp-open-sdk
+XTENSA_TOOLS_ROOT ?= /home/eric/esp8266/esp-open-sdk/xtensa-lx106-elf/bin
+
+# base directory of the ESP8266 SDK package, absolute
+# Note: Replace this one too
+SDK_BASE	?= /home/eric/esp8266/esp-open-sdk/sdk
+
+# esptool.py path and port
+ESPTOOL		?= $(XTENSA_TOOLS_ROOT)/esptool.py
+ESPPORT		?= /dev/ttyUSB0
+
+# name for the target project
+TARGET		= uart
+
+# which modules (subdirectories) of the project to include in compiling
+MODULES		= driver user
+EXTRA_INCDIR    = include
+
+# libraries used in this project, mainly provided by the SDK
+LIBS		= c gcc hal pp phy net80211 lwip wpa main
+
+# compiler flags using during compilation of source files
+#
+CFLAGS		= -Os -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals  -D__ets__ -DICACHE_FLASH
+
+# linker flags used to generate the main object file
+LDFLAGS		= -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
+
+# linker script used for the above linkier step
+LD_SCRIPT	= eagle.app.v6.ld
+
+# various paths from the SDK used in this project
+SDK_LIBDIR	= lib
+SDK_LDDIR	= ld
+SDK_INCDIR	= include include/json
+
+# we create two different files for uploading into the flash
+# these are the names and options to generate them
+FW_FILE_1_ADDR	= 0x00000
+FW_FILE_2_ADDR	= 0x10000
+
+# select which tools to use as compiler, librarian and linker
+CC		:= $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
+AR		:= $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar
+LD		:= $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
+
+
+
+####
+#### no user configurable options below here
+####
+SRC_DIR		:= $(MODULES)
+BUILD_DIR	:= $(addprefix $(BUILD_BASE)/,$(MODULES))
+
+SDK_LIBDIR	:= $(addprefix $(SDK_BASE)/,$(SDK_LIBDIR))
+SDK_INCDIR	:= $(addprefix -I$(SDK_BASE)/,$(SDK_INCDIR))
+
+SRC		:= $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
+OBJ		:= $(patsubst %.c,$(BUILD_BASE)/%.o,$(SRC))
+LIBS		:= $(addprefix -l,$(LIBS))
+APP_AR		:= $(addprefix $(BUILD_BASE)/,$(TARGET)_app.a)
+TARGET_OUT	:= $(addprefix $(BUILD_BASE)/,$(TARGET).out)
+
+LD_SCRIPT	:= $(addprefix -T$(SDK_BASE)/$(SDK_LDDIR)/,$(LD_SCRIPT))
+
+INCDIR	:= $(addprefix -I,$(SRC_DIR))
+EXTRA_INCDIR	:= $(addprefix -I,$(EXTRA_INCDIR))
+MODULE_INCDIR	:= $(addsuffix /include,$(INCDIR))
+
+FW_FILE_1	:= $(addprefix $(FW_BASE)/,$(FW_FILE_1_ADDR).bin)
+FW_FILE_2	:= $(addprefix $(FW_BASE)/,$(FW_FILE_2_ADDR).bin)
+
+V = $(VERBOSE)
+ifeq ("$(V)","1")
+Q :=
+vecho := @true
+else
+Q := @
+vecho := @echo
+endif
+
+vpath %.c $(SRC_DIR)
+
+define compile-objects
+$1/%.o: %.c
+	$(vecho) "CC $$<"
+	$(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@
+endef
+
+.PHONY: all checkdirs flash clean
+
+all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2)
+
+$(FW_BASE)/%.bin: $(TARGET_OUT) | $(FW_BASE)
+	$(vecho) "FW $(FW_BASE)/"
+	$(Q) $(ESPTOOL) elf2image -o $(FW_BASE)/ $(TARGET_OUT)
+
+$(TARGET_OUT): $(APP_AR)
+	$(vecho) "LD $@"
+	$(Q) $(LD) -L$(SDK_LIBDIR) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR) -Wl,--end-group -o $@
+
+$(APP_AR): $(OBJ)
+	$(vecho) "AR $@"
+	$(Q) $(AR) cru $@ $^
+
+checkdirs: $(BUILD_DIR) $(FW_BASE)
+
+$(BUILD_DIR):
+	$(Q) mkdir -p $@
+
+$(FW_BASE):
+	$(Q) mkdir -p $@
+
+flash: $(FW_FILE_1) $(FW_FILE_2)
+	$(ESPTOOL) --port $(ESPPORT) write_flash $(FW_FILE_1_ADDR) $(FW_FILE_1) $(FW_FILE_2_ADDR) $(FW_FILE_2)
+
+clean:
+	$(Q) rm -rf $(FW_BASE) $(BUILD_BASE)
+
+$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/README.md b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/README.md
new file mode 100644
index 000000000..e946c51e0
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/README.md
@@ -0,0 +1 @@
+# ESP8266_Wifi-Serial-Adapter
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/RingBuffer.c b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/RingBuffer.c
new file mode 100644
index 000000000..c1385c6e2
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/RingBuffer.c
@@ -0,0 +1,48 @@
+#include "driver/RingBuffer.h"
+
+#include <mem.h>
+#include <string.h>	//memcpy
+
+void RingBuffer_init(RingBuffer *buffer, uint16 size) {
+	buffer->front = 0;
+	buffer->back = 0;
+	buffer->size = size;
+
+	buffer->buffer = (uint8*)os_malloc(size);
+}
+
+void RingBuffer_addByte(RingBuffer *buffer, uint8 byte) {
+	buffer->buffer[buffer->back] = byte;
+
+	buffer->back = (buffer->back + 1) & (buffer->size - 1);
+}
+
+void RingBuffer_clear(RingBuffer *buffer) {
+	buffer->front = buffer->back = 0;
+}
+
+uint16_t RingBuffer_getSize(RingBuffer *buffer) {
+	return (buffer->back >= buffer->front) ? (buffer->back - buffer->front)
+		: (buffer->size + buffer->back - buffer->front);
+}
+
+uint16_t RingBuffer_get(RingBuffer *buffer, uint8 *out, uint16 outSize) {
+	uint16_t cpyAmt = RingBuffer_getSize(buffer);
+	if(cpyAmt > outSize)
+		cpyAmt = outSize;
+
+	if( (buffer->front + cpyAmt) > buffer->size ) {
+		uint16_t cpyRemainder = buffer->front + cpyAmt - buffer->size;
+		//Two copies
+		memcpy(out, buffer->buffer + buffer->front, cpyAmt - cpyRemainder);
+		memcpy(out + cpyAmt - cpyRemainder, buffer->buffer, cpyRemainder);
+	}
+	else {
+		//One copy
+		memcpy(out, buffer->buffer + buffer->front, cpyAmt);
+	}
+
+	buffer->front = (buffer->front + cpyAmt) & (buffer->size - 1);
+
+	return cpyAmt;
+}
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/uart.c b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/uart.c
new file mode 100644
index 000000000..fac75413d
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/driver/uart.c
@@ -0,0 +1,521 @@
+/*
+ * File	: uart.c
+ * Copyright (C) 2013 - 2016, Espressif Systems
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "ets_sys.h"
+#include "osapi.h"
+#include "driver/uart.h"
+#include "osapi.h"
+#include "driver/uart_register.h"
+#include "mem.h"
+#include "os_type.h"
+#include "driver/RingBuffer.h"
+
+#define BUFFER_SIZE	2048
+
+//static volatile RingBuffer _rxBuffer;
+static volatile uint8 _rxBuffer[BUFFER_SIZE];
+static volatile uint16 _rxLen;
+static volatile uint32 _intFlags;
+
+// UartDev is defined and initialized in rom code.
+extern UartDevice    UartDev;
+
+LOCAL void uart0_rx_intr_handler(void *para);
+
+/******************************************************************************
+ * FunctionName : uart_config
+ * Description  : Internal used function
+ *                UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
+ *                UART1 just used for debug output
+ * Parameters   : uart_no, use UART0 or UART1 defined ahead
+ * Returns      : NONE
+*******************************************************************************/
+LOCAL void ICACHE_FLASH_ATTR
+uart_config(uint8 uart_no)
+{
+    if (uart_no == UART1){
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
+    }else{
+        ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, NULL);
+        PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
+    }
+    uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE
+    
+    WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M)  <<  UART_PARITY_EN_S) //SET BIT AND PARITY MODE
+                                                                        | ((UartDev.parity & UART_PARITY_M)  <<UART_PARITY_S )
+                                                                        | ((UartDev.stop_bits & UART_STOP_BIT_NUM) << UART_STOP_BIT_NUM_S)
+                                                                        | ((UartDev.data_bits & UART_BIT_NUM) << UART_BIT_NUM_S));
+    
+    //clear rx and tx fifo,not ready
+    SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);    //RESET FIFO
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
+    
+    if (uart_no == UART0){
+        //set rx fifo trigger
+        WRITE_PERI_REG(UART_CONF1(uart_no),
+        ((UART_RX_FULL_LEVEL & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
+        ((UART_RX_TO_LEVEL & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S) |
+        UART_RX_TOUT_EN|
+        ((0x10 & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S));//wjl 
+        SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA |UART_FRM_ERR_INT_ENA);
+    }else{
+        WRITE_PERI_REG(UART_CONF1(uart_no),((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));//TrigLvl default val == 1
+    }
+    //clear all interrupt
+    WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
+    //enable rx_interrupt
+    SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_OVF_INT_ENA|UART_RXFIFO_TOUT_INT_ENA|UART_FRM_ERR_INT_ENA|UART_PARITY_ERR_INT_ENA);
+}
+
+uint16 uart_get(uint8 *out, uint16 len) {
+	//uart_rx_intr_disable(UART0);
+
+  uint16 amount = (_rxLen < len) ? _rxLen : len;
+
+  memcpy(out, (uint8*)_rxBuffer, amount);
+
+	if(amount != _rxLen) {
+		memcpy((uint8*)_rxBuffer, (uint8*)_rxBuffer + amount, _rxLen - amount);
+	}
+  _rxLen -= amount;
+
+	//uart_rx_intr_enable(UART0);
+
+	return amount;
+/*
+	//Grab the data from the FIFO
+	uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)
+		& UART_RXFIFO_CNT;
+	
+	uint8 i;
+
+	for(i = 0; i < fifo_len; ++i) {
+		//uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
+		//RingBuffer_addByte((RingBuffer*)&_rxBuffer, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
+		out[i] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
+	}
+
+	//Re-enable UART RX interrupts
+	SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
+
+	return fifo_len;
+*/
+}
+
+uint16 uart_getFifoLen() {
+	uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)
+		& UART_RXFIFO_CNT;
+	
+	return fifo_len;
+}
+
+uint8 uart_getTxFifoAvail() {
+	uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_TXFIFO_CNT_S)
+		& UART_TXFIFO_CNT;
+	
+	return UART_FIFO_LEN - fifo_len;
+}
+
+/******************************************************************************
+ * FunctionName : uart1_tx_one_char
+ * Description  : Internal used function
+ *                Use uart1 interface to transfer one char
+ * Parameters   : uint8 TxChar - character to tx
+ * Returns      : OK
+*******************************************************************************/
+ STATUS uart_tx_one_char(uint8 uart, uint8 TxChar)
+{
+    while (true){
+        uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
+        if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
+            break;
+        }
+    }
+    WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
+    return OK;
+}
+
+void uart_set_txto() {
+	_intFlags |= UART_TXFIFO_EMPTY_INT_ENA;
+
+	uart_rx_intr_enable(UART0);
+}
+
+void uart_clear_txto() {
+	uart_rx_intr_disable(UART0);
+
+	_intFlags &= ~(UART_TXFIFO_EMPTY_INT_ENA);
+
+	uart_rx_intr_enable(UART0);
+}
+
+
+/******************************************************************************
+ * FunctionName : uart0_tx_buffer
+ * Description  : use uart0 to transfer buffer
+ * Parameters   : uint8 *buf - point to send buffer
+ *                uint16 len - buffer len
+ * Returns      :
+*******************************************************************************/
+void ICACHE_FLASH_ATTR
+uart0_tx_buffer(uint8 *buf, uint16 len)
+{
+    uint16 i;
+    for (i = 0; i < len; i++)
+    {
+        uart_tx_one_char(UART0, buf[i]);
+    }
+}
+
+/******************************************************************************
+ * FunctionName : uart0_sendStr
+ * Description  : use uart0 to transfer buffer
+ * Parameters   : uint8 *buf - point to send buffer
+ *                uint16 len - buffer len
+ * Returns      :
+*******************************************************************************/
+void ICACHE_FLASH_ATTR
+uart0_sendStr(const char *str)
+{
+    while(*str){
+        uart_tx_one_char(UART0, *str++);
+    }
+}
+
+void uart_rx_flush() {
+  volatile uint8 byte;
+
+  uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)
+	  & UART_RXFIFO_CNT;
+
+	while((fifo_len--) > 0) {
+	  byte = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
+	}
+}
+
+/******************************************************************************
+ * FunctionName : uart0_rx_intr_handler
+ * Description  : Internal used function
+ *                UART0 interrupt handler, add self handle code inside
+ * Parameters   : void *para - point to ETS_UART_INTR_ATTACH's arg
+ * Returns      : NONE
+*******************************************************************************/
+LOCAL void
+uart0_rx_intr_handler(void *para)
+{
+	uint32 intMask = 0;
+	uint8_t uart_no = UART0;
+	
+    /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
+    * uart1 and uart0 respectively
+    */
+    //uint8 RcvChar;
+    //uint8 uart_no = UART0;//UartDev.buff_uart_no;
+    //uint8 fifo_len = 0;
+    //uint8 buf_idx = 0;
+    //uint8 temp,cnt;
+    //RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
+		uint8 read = 0;
+    
+    	/*ATTENTION:*/
+	/*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
+	/*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
+	/*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */
+		if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){
+				//recv = 1;
+				//intMask = UART_RXFIFO_FULL_INT_CLR;
+
+				//Disable this interrupt until we read the data from the fifo
+				//CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
+
+        //system_os_post(UART_TASK_PRIORITY, UART_SIG_RECV, 0);
+
+				//Clear interrupt flag
+				//WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
+
+				//uint16 count = uart_get((uint8*)_rxBuffer + _rxLen, BUFFER_SIZE - _rxLen);
+				//_rxLen += count;
+				read = 1;
+				intMask = UART_RXFIFO_FULL_INT_CLR;
+    }
+		else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)){
+				//recv = 1;
+				intMask = UART_RXFIFO_TOUT_INT_CLR;
+				
+				//Disable this interrupt until we read the data from the fifo
+				//CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_RXFIFO_TOUT_INT_ENA | UART_RXFIFO_FULL_INT_ENA);
+
+        //system_os_post(UART_TASK_PRIORITY, UART_SIG_RECV, 0);
+
+				//Clear interrupt flag
+				WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
+
+				//uint16 count = uart_get((uint8*)_rxBuffer + _rxLen, BUFFER_SIZE - _rxLen);
+				//_rxLen += count;
+				read = 1;
+
+    }
+		else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)){
+			CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
+      
+			//_intFlags &= ~(UART_TXFIFO_EMPTY_INT_ENA);
+
+			system_os_post(UART_TASK_PRIORITY, UART_SIG_TXTO, 0);
+      WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);
+        
+    }
+		else if(UART_RXFIFO_OVF_INT_ST  == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)){
+        system_os_post(UART_TASK_PRIORITY, UART_SIG_RXOVF, 0);
+				
+				WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR);
+    }
+		else if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) {
+			system_os_post(UART_TASK_PRIORITY, UART_SIG_ERR_FRM, 0);
+
+			WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
+		}
+		else if(UART_PARITY_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_PARITY_ERR_INT_ST)) {
+			//system_os_post(UART_TASK_PRIORITY, UART_SIG_ERR_PARITY, 0);
+
+			WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_PARITY_ERR_INT_CLR);
+		}
+
+
+	if(read) {
+		//Grab data from FIFO
+		uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)
+			& UART_RXFIFO_CNT;
+
+		while((fifo_len--) > 0) {
+			//uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
+			//RingBuffer_addByte((RingBuffer*)&_rxBuffer, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
+      _rxBuffer[_rxLen++] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
+		}
+
+		//Clear int flag
+		WRITE_PERI_REG(UART_INT_CLR(UART0), intMask);
+
+    //Post receive message
+    system_os_post(UART_TASK_PRIORITY, UART_SIG_RECV, 0);
+	}
+
+}
+
+/******************************************************************************
+ * FunctionName : uart_init
+ * Description  : user interface for init uart
+ * Parameters   : UartBautRate uart0_br - uart0 bautrate
+ *                UartBautRate uart1_br - uart1 bautrate
+ * Returns      : NONE
+*******************************************************************************/
+void ICACHE_FLASH_ATTR
+uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
+{
+    /*this is a example to process uart data from task,please change the priority to fit your application task if exists*/
+    //system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen);  //demo with a task to process the uart data
+    
+		//RingBuffer_init((RingBuffer*)&_rxBuffer);
+    _rxLen = 0;
+
+		_intFlags = UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_OVF_INT_ENA|UART_RXFIFO_TOUT_INT_ENA;
+
+    UartDev.baut_rate = uart0_br;
+    uart_config(UART0);
+    
+		UartDev.baut_rate = uart1_br;
+    uart_config(UART1);
+    
+		ETS_UART_INTR_ENABLE();
+    
+
+    /*option 1: use default print, output from uart0 , will wait some time if fifo is full */
+    //do nothing...
+
+    /*option 2: output from uart1,uart1 output will not wait , just for output debug info */
+    /*os_printf output uart data via uart1(GPIO2)*/
+    //os_install_putc1((void *)uart1_write_char);    //use this one to output debug information via uart1 //
+
+    /*option 3: output from uart0 will skip current byte if fifo is full now... */
+    /*see uart0_write_char_no_wait:you can output via a buffer or output directly */
+    /*os_printf output uart data via uart0 or uart buffer*/
+    //os_install_putc1((void *)uart0_write_char_no_wait);  //use this to print via uart0
+}
+
+/******************************************************************************
+ * FunctionName : uart_tx_one_char_no_wait
+ * Description  : uart tx a single char without waiting for fifo 
+ * Parameters   : uint8 uart - uart port
+ *                uint8 TxChar - char to tx
+ * Returns      : STATUS
+*******************************************************************************/
+STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar)
+{
+    uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
+    if (fifo_cnt < 126) {
+        WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
+    }
+    return OK;
+}
+
+STATUS uart0_tx_one_char_no_wait(uint8 TxChar)
+{
+    uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
+    if (fifo_cnt < 126) {
+        WRITE_PERI_REG(UART_FIFO(UART0) , TxChar);
+    }
+    return OK;
+}
+
+void uart_debugSend(char *str) {
+#ifndef DEBUG
+	return;
+#else
+	uart0_send_nowait(str, os_strlen(str));
+#endif
+}
+
+uint16 uart0_send_nowait(uint8 *buffer, uint16 len) {
+	uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
+
+	uint8 written = 0;
+
+	if(fifo_cnt < UART_FIFO_LEN) {
+		uint8 avail = UART_FIFO_LEN - fifo_cnt;
+		if(avail > len)
+			avail = len;
+
+		written = avail;
+
+		while( (avail--) > 0 ) {
+			WRITE_PERI_REG(UART_FIFO(UART0), *(buffer++));
+		}
+	}
+
+	return written;
+}
+
+
+/******************************************************************************
+ * FunctionName : uart1_sendStr_no_wait
+ * Description  : uart tx a string without waiting for every char, used for print debug info which can be lost
+ * Parameters   : const char *str - string to be sent
+ * Returns      : NONE
+*******************************************************************************/
+void uart1_sendStr_no_wait(const char *str)
+{
+    while(*str){
+        uart_tx_one_char_no_wait(UART1, *str++);
+    }
+}
+
+
+void uart_rx_intr_disable(uint8 uart_no)
+{
+    CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), _intFlags);
+}
+
+void uart_rx_intr_enable(uint8 uart_no)
+{
+    SET_PERI_REG_MASK(UART_INT_ENA(uart_no), _intFlags);
+}
+
+
+void ICACHE_FLASH_ATTR
+UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len) 
+{
+    SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_BIT_NUM,len,UART_BIT_NUM_S);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num) 
+{
+    SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_STOP_BIT_NUM,bit_num,UART_STOP_BIT_NUM_S);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask) 
+{
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK);
+    SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetParity(uint8 uart_no, UartParityMode Parity_mode) 
+{
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY |UART_PARITY_EN);
+    if(Parity_mode==NONE_BITS){
+    }else{
+        SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode|UART_PARITY_EN);
+    }
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetBaudrate(uint8 uart_no,uint32 baud_rate)
+{
+    uart_div_modify(uart_no, UART_CLK_FREQ /baud_rate);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh)
+{
+    if(flow_ctrl&USART_HardwareFlowControl_RTS){
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
+        SET_PERI_REG_BITS(UART_CONF1(uart_no),UART_RX_FLOW_THRHD,rx_thresh,UART_RX_FLOW_THRHD_S);
+        SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
+    }else{
+        CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
+    }
+    if(flow_ctrl&USART_HardwareFlowControl_CTS){
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS);
+        SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
+    }else{
+        CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
+    }
+}
+
+void ICACHE_FLASH_ATTR
+UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us) //do not use if tx flow control enabled
+{
+    uint32 t_s = system_get_time();
+    while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)){
+		
+        if(( system_get_time() - t_s )> time_out_us){
+            break;
+        }
+	WRITE_PERI_REG(0X60000914, 0X73);//WTD
+
+    }
+}
+
+void ICACHE_FLASH_ATTR
+UART_ResetFifo(uint8 uart_no)
+{
+    SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
+}
+
+void ICACHE_FLASH_ATTR
+UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask)
+{
+    WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetIntrEna(uint8 uart_no,uint32 ena_mask)
+{
+    SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask);
+}
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/RingBuffer.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/RingBuffer.h
new file mode 100644
index 000000000..3934fcf3b
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/RingBuffer.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "os_type.h"
+
+typedef struct {
+	uint8 *buffer;
+	uint16 front, back, size;
+} RingBuffer;
+
+
+void RingBuffer_init(RingBuffer *buffer, uint16 size);
+
+void RingBuffer_addByte(RingBuffer *buffer, uint8 byte);
+
+void RingBuffer_put(RingBuffer *buffer, uint8 *data, uint16 len);
+
+void RingBuffer_clear(RingBuffer *buffer);
+
+uint16_t RingBuffer_getSize(RingBuffer *buffer);
+
+uint16_t RingBuffer_get(RingBuffer *buffer, uint8 *out, uint16 outSize);
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart.h
new file mode 100644
index 000000000..c0b9a2780
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart.h
@@ -0,0 +1,219 @@
+/*
+ * File	: uart.h
+ * Copyright (C) 2013 - 2016, Espressif Systems
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef UART_APP_H
+#define UART_APP_H
+
+#include "uart_register.h"
+#include "eagle_soc.h"
+#include "c_types.h"
+
+#define UART0   0
+#define UART1   1
+
+#define UART_SIG_RECV		0x01
+#define UART_SIG_TXTO		0x02
+#define UART_SIG_RXOVF	0x03
+#define UART_SIG_ERR_FRM	0x04
+#define UART_SIG_ERR_PARITY	0x05
+#define UART_TASK_PRIORITY	2
+
+#define UART_RX_FULL_LEVEL	(100)
+#define UART_RX_TO_LEVEL	(10)
+
+//#define DEBUG	1
+
+typedef enum {
+    FIVE_BITS = 0x0,
+    SIX_BITS = 0x1,
+    SEVEN_BITS = 0x2,
+    EIGHT_BITS = 0x3
+} UartBitsNum4Char;
+
+typedef enum {
+    ONE_STOP_BIT             = 0x1,
+    ONE_HALF_STOP_BIT        = 0x2,
+    TWO_STOP_BIT             = 0x3
+} UartStopBitsNum;
+
+typedef enum {
+    NONE_BITS = 0x2,
+    ODD_BITS   = 1,
+    EVEN_BITS = 0
+} UartParityMode;
+
+typedef enum {
+    STICK_PARITY_DIS   = 0,
+    STICK_PARITY_EN    = 1
+} UartExistParity;
+
+typedef enum {
+    UART_None_Inverse = 0x0,
+    UART_Rxd_Inverse = UART_RXD_INV,
+    UART_CTS_Inverse = UART_CTS_INV,
+    UART_Txd_Inverse = UART_TXD_INV,
+    UART_RTS_Inverse = UART_RTS_INV,
+} UART_LineLevelInverse;
+
+
+typedef enum {
+    BIT_RATE_300 = 300,
+    BIT_RATE_600 = 600,
+    BIT_RATE_1200 = 1200,
+    BIT_RATE_2400 = 2400,
+    BIT_RATE_4800 = 4800,
+    BIT_RATE_9600   = 9600,
+    BIT_RATE_19200  = 19200,
+    BIT_RATE_38400  = 38400,
+    BIT_RATE_57600  = 57600,
+    BIT_RATE_74880  = 74880,
+    BIT_RATE_115200 = 115200,
+    BIT_RATE_230400 = 230400,
+    BIT_RATE_460800 = 460800,
+    BIT_RATE_921600 = 921600,
+    BIT_RATE_1843200 = 1843200,
+    BIT_RATE_3686400 = 3686400,
+} UartBautRate;
+
+typedef enum {
+    NONE_CTRL,
+    HARDWARE_CTRL,
+    XON_XOFF_CTRL
+} UartFlowCtrl;
+
+typedef enum {
+    USART_HardwareFlowControl_None = 0x0,
+    USART_HardwareFlowControl_RTS = 0x1,
+    USART_HardwareFlowControl_CTS = 0x2,
+    USART_HardwareFlowControl_CTS_RTS = 0x3
+} UART_HwFlowCtrl;
+
+typedef enum {
+    EMPTY,
+    UNDER_WRITE,
+    WRITE_OVER
+} RcvMsgBuffState;
+
+typedef struct {
+    uint32     RcvBuffSize;
+    uint8     *pRcvMsgBuff;
+    uint8     *pWritePos;
+    uint8     *pReadPos;
+    uint8      TrigLvl; //JLU: may need to pad
+    RcvMsgBuffState  BuffState;
+} RcvMsgBuff;
+
+typedef struct {
+    uint32   TrxBuffSize;
+    uint8   *pTrxBuff;
+} TrxMsgBuff;
+
+typedef enum {
+    BAUD_RATE_DET,
+    WAIT_SYNC_FRM,
+    SRCH_MSG_HEAD,
+    RCV_MSG_BODY,
+    RCV_ESC_CHAR,
+} RcvMsgState;
+
+typedef struct {
+    UartBautRate 	     baut_rate;
+    UartBitsNum4Char  data_bits;
+    UartExistParity      exist_parity;
+    UartParityMode 	    parity;    
+    UartStopBitsNum   stop_bits;
+    UartFlowCtrl         flow_ctrl;
+    RcvMsgBuff          rcv_buff;
+    TrxMsgBuff           trx_buff;
+    RcvMsgState        rcv_state;
+    int                      received;
+    int                      buff_uart_no;  //indicate which uart use tx/rx buffer
+} UartDevice;
+
+void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
+void uart0_sendStr(const char *str);
+uint16 uart0_send_nowait(uint8 *buffer, uint16 len);
+void uart_debugSend(char *str);
+void uart_set_txto();
+void uart_clear_txto();
+uint16 uart_getFifoLen();
+uint8 uart_getTxFifoAvail();
+
+
+///////////////////////////////////////
+#define UART_FIFO_LEN  126  //define the tx fifo length
+#define UART_TX_EMPTY_THRESH_VAL 0x10
+
+
+ struct UartBuffer{
+    uint32     UartBuffSize;
+    uint8     *pUartBuff;
+    uint8     *pInPos;
+    uint8     *pOutPos;
+    STATUS  BuffState;
+    uint16    Space;  //remanent space of the buffer
+    uint8  TcpControl;
+    struct  UartBuffer     *  nextBuff;
+};
+
+struct UartRxBuff{
+    uint32     UartRxBuffSize;
+    uint8     *pUartRxBuff;
+    uint8     *pWritePos;
+    uint8     *pReadPos;
+    STATUS RxBuffState;
+    uint32    Space;  //remanent space of the buffer
+} ;
+
+typedef enum {
+    RUN = 0,
+    BLOCK = 1,
+} TCPState;
+
+//void ICACHE_FLASH_ATTR uart_test_rx();
+STATUS uart_tx_one_char(uint8 uart, uint8 TxChar);
+STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar);
+void  uart1_sendStr_no_wait(const char *str);
+struct UartBuffer*  Uart_Buf_Init();
+
+
+void  uart_rx_intr_enable(uint8 uart_no);
+void  uart_rx_intr_disable(uint8 uart_no);
+void uart0_tx_buffer(uint8 *buf, uint16 len);
+uint16 uart_get(uint8 *out, uint16 len);
+void uart_rx_flush();
+
+//==============================================
+#define FUNC_UART0_CTS 4
+#define FUNC_U0CTS                      4
+#define FUNC_U1TXD_BK                   2
+#define UART_LINE_INV_MASK  (0x3f<<19)
+void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len);
+void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num);
+void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask);
+void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode);
+void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate);
+void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh);
+void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled
+void UART_ResetFifo(uint8 uart_no);
+void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask);
+void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask);
+void UART_SetPrintPort(uint8 uart_no);
+bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us);
+//==============================================
+
+#endif
+
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart_register.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart_register.h
new file mode 100644
index 000000000..05f6ceaf2
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/driver/uart_register.h
@@ -0,0 +1,156 @@
+/*
+ * File	: uart_register.h
+ * Copyright (C) 2013 - 2016, Espressif Systems
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+ *  Copyright (c) 2010 - 2011 Espressif System
+ *
+ */
+
+#ifndef UART_REGISTER_H_
+#define UART_REGISTER_H_
+
+#define REG_UART_BASE(i)                (0x60000000 + (i)*0xf00)
+//version value:32'h062000
+
+#define UART_FIFO(i)                    (REG_UART_BASE(i) + 0x0)
+#define UART_RXFIFO_RD_BYTE                 0x000000FF
+#define UART_RXFIFO_RD_BYTE_S               0
+
+#define UART_INT_RAW(i)                 (REG_UART_BASE(i) + 0x4)
+#define UART_RXFIFO_TOUT_INT_RAW            (BIT(8))
+#define UART_BRK_DET_INT_RAW                (BIT(7))
+#define UART_CTS_CHG_INT_RAW                (BIT(6))
+#define UART_DSR_CHG_INT_RAW                (BIT(5))
+#define UART_RXFIFO_OVF_INT_RAW             (BIT(4))
+#define UART_FRM_ERR_INT_RAW                (BIT(3))
+#define UART_PARITY_ERR_INT_RAW             (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_RAW           (BIT(1))
+#define UART_RXFIFO_FULL_INT_RAW            (BIT(0))
+
+#define UART_INT_ST(i)                  (REG_UART_BASE(i) + 0x8)
+#define UART_RXFIFO_TOUT_INT_ST             (BIT(8))
+#define UART_BRK_DET_INT_ST                 (BIT(7))
+#define UART_CTS_CHG_INT_ST                 (BIT(6))
+#define UART_DSR_CHG_INT_ST                 (BIT(5))
+#define UART_RXFIFO_OVF_INT_ST              (BIT(4))
+#define UART_FRM_ERR_INT_ST                 (BIT(3))
+#define UART_PARITY_ERR_INT_ST              (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_ST            (BIT(1))
+#define UART_RXFIFO_FULL_INT_ST             (BIT(0))
+
+#define UART_INT_ENA(i)                 (REG_UART_BASE(i) + 0xC)
+#define UART_RXFIFO_TOUT_INT_ENA            (BIT(8))
+#define UART_BRK_DET_INT_ENA                (BIT(7))
+#define UART_CTS_CHG_INT_ENA                (BIT(6))
+#define UART_DSR_CHG_INT_ENA                (BIT(5))
+#define UART_RXFIFO_OVF_INT_ENA             (BIT(4))
+#define UART_FRM_ERR_INT_ENA                (BIT(3))
+#define UART_PARITY_ERR_INT_ENA             (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_ENA           (BIT(1))
+#define UART_RXFIFO_FULL_INT_ENA            (BIT(0))
+
+#define UART_INT_CLR(i)                 (REG_UART_BASE(i) + 0x10)
+#define UART_RXFIFO_TOUT_INT_CLR            (BIT(8))
+#define UART_BRK_DET_INT_CLR                (BIT(7))
+#define UART_CTS_CHG_INT_CLR                (BIT(6))
+#define UART_DSR_CHG_INT_CLR                (BIT(5))
+#define UART_RXFIFO_OVF_INT_CLR             (BIT(4))
+#define UART_FRM_ERR_INT_CLR                (BIT(3))
+#define UART_PARITY_ERR_INT_CLR             (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_CLR           (BIT(1))
+#define UART_RXFIFO_FULL_INT_CLR            (BIT(0))
+
+#define UART_CLKDIV(i)                  (REG_UART_BASE(i) + 0x14)
+#define UART_CLKDIV_CNT                     0x000FFFFF
+#define UART_CLKDIV_S                       0
+
+#define UART_AUTOBAUD(i)                (REG_UART_BASE(i) + 0x18)
+#define UART_GLITCH_FILT                    0x000000FF
+#define UART_GLITCH_FILT_S                  8
+#define UART_AUTOBAUD_EN                    (BIT(0))
+
+#define UART_STATUS(i)                  (REG_UART_BASE(i) + 0x1C)
+#define UART_TXD                            (BIT(31))
+#define UART_RTSN                           (BIT(30))
+#define UART_DTRN                           (BIT(29))
+#define UART_TXFIFO_CNT                     0x000000FF
+#define UART_TXFIFO_CNT_S                   16
+#define UART_RXD                            (BIT(15))
+#define UART_CTSN                           (BIT(14))
+#define UART_DSRN                           (BIT(13))
+#define UART_RXFIFO_CNT                     0x000000FF
+#define UART_RXFIFO_CNT_S                   0
+
+#define UART_CONF0(i)                   (REG_UART_BASE(i) + 0x20)
+#define UART_DTR_INV                        (BIT(24))
+#define UART_RTS_INV                        (BIT(23))
+#define UART_TXD_INV                        (BIT(22))
+#define UART_DSR_INV                        (BIT(21))
+#define UART_CTS_INV                        (BIT(20))
+#define UART_RXD_INV                        (BIT(19))
+#define UART_TXFIFO_RST                     (BIT(18))
+#define UART_RXFIFO_RST                     (BIT(17))
+#define UART_IRDA_EN                        (BIT(16))
+#define UART_TX_FLOW_EN                     (BIT(15))
+#define UART_LOOPBACK                       (BIT(14))
+#define UART_IRDA_RX_INV                    (BIT(13))
+#define UART_IRDA_TX_INV                    (BIT(12))
+#define UART_IRDA_WCTL                      (BIT(11))
+#define UART_IRDA_TX_EN                     (BIT(10))
+#define UART_IRDA_DPLX                      (BIT(9))
+#define UART_TXD_BRK                        (BIT(8))
+#define UART_SW_DTR                         (BIT(7))
+#define UART_SW_RTS                         (BIT(6))
+#define UART_STOP_BIT_NUM                   0x00000003
+#define UART_STOP_BIT_NUM_S                 4
+#define UART_BIT_NUM                        0x00000003
+#define UART_BIT_NUM_S                      2
+#define UART_PARITY_EN                      (BIT(1))
+#define UART_PARITY_EN_M                0x00000001
+#define UART_PARITY_EN_S                 1
+#define UART_PARITY                         (BIT(0))
+#define UART_PARITY_M                       0x00000001
+#define UART_PARITY_S                        0
+
+#define UART_CONF1(i)                   (REG_UART_BASE(i) + 0x24)
+#define UART_RX_TOUT_EN                     (BIT(31))
+#define UART_RX_TOUT_THRHD                  0x0000007F
+#define UART_RX_TOUT_THRHD_S                24
+#define UART_RX_FLOW_EN                     (BIT(23))
+#define UART_RX_FLOW_THRHD                  0x0000007F
+#define UART_RX_FLOW_THRHD_S                16
+#define UART_TXFIFO_EMPTY_THRHD             0x0000007F
+#define UART_TXFIFO_EMPTY_THRHD_S           8
+#define UART_RXFIFO_FULL_THRHD              0x0000007F
+#define UART_RXFIFO_FULL_THRHD_S            0
+
+#define UART_LOWPULSE(i)                (REG_UART_BASE(i) + 0x28)
+#define UART_LOWPULSE_MIN_CNT               0x000FFFFF
+#define UART_LOWPULSE_MIN_CNT_S             0
+
+#define UART_HIGHPULSE(i)               (REG_UART_BASE(i) + 0x2C)
+#define UART_HIGHPULSE_MIN_CNT              0x000FFFFF
+#define UART_HIGHPULSE_MIN_CNT_S            0
+
+#define UART_PULSE_NUM(i)               (REG_UART_BASE(i) + 0x30)
+#define UART_PULSE_NUM_CNT                  0x0003FF
+#define UART_PULSE_NUM_CNT_S                0
+
+#define UART_DATE(i)                    (REG_UART_BASE(i) + 0x78)
+#define UART_ID(i)                      (REG_UART_BASE(i) + 0x7C)
+
+#endif // UART_REGISTER_H_INCLUDED
+
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/espmissingincludes.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/espmissingincludes.h
new file mode 100644
index 000000000..3541f4084
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/espmissingincludes.h
@@ -0,0 +1,78 @@
+#ifndef ESPMISSINGINCLUDES_H
+#define ESPMISSINGINCLUDES_H
+
+#include <stdint.h>
+#include <c_types.h>
+
+#include "os_type.h"
+
+int strcasecmp(const char *a, const char *b);
+#ifndef FREERTOS
+#include <eagle_soc.h>
+#include <ets_sys.h>
+//Missing function prototypes in include folders. Gcc will warn on these if we don't define 'em anywhere.
+//MOST OF THESE ARE GUESSED! but they seem to swork and shut up the compiler.
+typedef struct espconn espconn;
+
+int atoi(const char *nptr);
+void ets_install_putc1(void *routine);
+void ets_isr_attach(int intr, void *handler, void *arg);
+void ets_isr_mask(unsigned intr);
+void ets_isr_unmask(unsigned intr);
+int ets_memcmp(const void *s1, const void *s2, size_t n);
+void *ets_memcpy(void *dest, const void *src, size_t n);
+void *ets_memset(void *s, int c, size_t n);
+int ets_sprintf(char *str, const char *format, ...)  __attribute__ ((format (printf, 2, 3)));
+int ets_str2macaddr(void *, void *);
+int ets_strcmp(const char *s1, const char *s2);
+char *ets_strcpy(char *dest, const char *src);
+size_t ets_strlen(const char *s);
+int ets_strncmp(const char *s1, const char *s2, int len);
+char *ets_strncpy(char *dest, const char *src, size_t n);
+char *ets_strstr(const char *haystack, const char *needle);
+void ets_timer_arm_new(os_timer_t *a, int b, int c, int isMstimer);
+void ets_timer_disarm(os_timer_t *a);
+void ets_timer_setfn(os_timer_t *t, ETSTimerFunc *fn, void *parg);
+void ets_update_cpu_frequency(int freqmhz);
+void *os_memmove(void *dest, const void *src, size_t n);
+int os_printf(const char *format, ...)  __attribute__ ((format (printf, 1, 2)));
+int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (printf, 3, 4)));
+int os_printf_plus(const char *format, ...)  __attribute__ ((format (printf, 1, 2)));
+void uart_div_modify(int no, unsigned int freq);
+uint8 wifi_get_opmode(void);
+uint32 system_get_time();
+int rand(void);
+void ets_bzero(void *s, size_t n);
+void ets_delay_us(int ms);
+
+//Hack: this is defined in SDK 1.4.0 and undefined in 1.3.0. It's only used for this, the symbol itself
+//has no meaning here.
+#ifndef RC_LIMIT_P2P_11N
+//Defs for SDK <1.4.0
+void *pvPortMalloc(size_t xWantedSize);
+void *pvPortZalloc(size_t);
+void vPortFree(void *ptr);
+void *vPortMalloc(size_t xWantedSize);
+void pvPortFree(void *ptr);
+#else
+void *pvPortMalloc(size_t xWantedSize, const char *file, int line);
+void *pvPortZalloc(size_t, const char *file, int line);
+void vPortFree(void *ptr, const char *file, int line);
+void *vPortMalloc(size_t xWantedSize, const char *file, int line);
+void pvPortFree(void *ptr, const char *file, int line);
+#endif
+
+//Standard PIN_FUNC_SELECT gives a warning. Replace by a non-warning one.
+#ifdef PIN_FUNC_SELECT
+#undef PIN_FUNC_SELECT
+#define PIN_FUNC_SELECT(PIN_NAME, FUNC)  do { \
+    WRITE_PERI_REG(PIN_NAME,   \
+                                (READ_PERI_REG(PIN_NAME) \
+                                     &  (~(PERIPHS_IO_MUX_FUNC<<PERIPHS_IO_MUX_FUNC_S)))  \
+                                     |( (((FUNC&BIT2)<<2)|(FUNC&0x3))<<PERIPHS_IO_MUX_FUNC_S) );  \
+    } while (0)
+#endif
+
+#endif
+
+#endif
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/user_config.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/user_config.h
new file mode 100644
index 000000000..e69de29bb
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/user_tcp.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/user_tcp.h
new file mode 100644
index 000000000..f0a2434a6
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/include/user_tcp.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "os_type.h"
+
+typedef void (*ReceiveHandler)(uint16 len);
+
+void tcp_start(uint16 port);
+void tcp_stop();
+
+void tcp_setRecvHandler(ReceiveHandler handler);
+
+void tcp_send(uint8* buffer, uint16 len);
+uint16 tcp_receive(uint8* buffer, uint16 size);
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.c b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.c
new file mode 100644
index 000000000..f7e68ee6d
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.c
@@ -0,0 +1,443 @@
+/*
+ * File	: uart.c
+ * Copyright (C) 2013 - 2016, Espressif Systems
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "ets_sys.h"
+#include "osapi.h"
+#include "driver/uart.h"
+#include "osapi.h"
+#include "driver/uart_register.h"
+#include "mem.h"
+#include "os_type.h"
+#include "driver/RingBuffer.h"
+
+//static volatile RingBuffer _rxBuffer;
+static volatile uint8 _rxBuffer[BUFFER_SIZE];
+static volatile uint16 _rxLen;
+static volatile uint32 _intFlags;
+
+// UartDev is defined and initialized in rom code.
+extern UartDevice    UartDev;
+
+LOCAL void uart0_rx_intr_handler(void *para);
+
+/******************************************************************************
+ * FunctionName : uart_config
+ * Description  : Internal used function
+ *                UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
+ *                UART1 just used for debug output
+ * Parameters   : uart_no, use UART0 or UART1 defined ahead
+ * Returns      : NONE
+*******************************************************************************/
+LOCAL void ICACHE_FLASH_ATTR
+uart_config(uint8 uart_no)
+{
+    if (uart_no == UART1){
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
+    }else{
+        ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, NULL);
+        PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
+    }
+    uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE
+    
+    WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M)  <<  UART_PARITY_EN_S) //SET BIT AND PARITY MODE
+                                                                        | ((UartDev.parity & UART_PARITY_M)  <<UART_PARITY_S )
+                                                                        | ((UartDev.stop_bits & UART_STOP_BIT_NUM) << UART_STOP_BIT_NUM_S)
+                                                                        | ((UartDev.data_bits & UART_BIT_NUM) << UART_BIT_NUM_S));
+    
+    //clear rx and tx fifo,not ready
+    SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);    //RESET FIFO
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
+    
+    if (uart_no == UART0){
+        //set rx fifo trigger
+        WRITE_PERI_REG(UART_CONF1(uart_no),
+        ((100 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
+        (4 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |
+        UART_RX_TOUT_EN|
+        ((0x10 & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S));//wjl 
+        SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA |UART_FRM_ERR_INT_ENA);
+    }else{
+        WRITE_PERI_REG(UART_CONF1(uart_no),((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));//TrigLvl default val == 1
+    }
+    //clear all interrupt
+    WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
+    //enable rx_interrupt
+    SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_OVF_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
+}
+
+uint16 uart_get(uint8 *out, uint16 len) {
+	uart_rx_intr_disable(UART0);
+
+	//uint16 amount = RingBuffer_get((RingBuffer*)&_rxBuffer, out, len);
+  uint16 amount = (_rxLen < len) ? _rxLen : len;
+
+  memcpy(out, (uint8*)_rxBuffer, amount);
+  _rxLen -= amount;
+
+	uart_rx_intr_enable(UART0);
+
+	return amount;
+}
+
+/******************************************************************************
+ * FunctionName : uart1_tx_one_char
+ * Description  : Internal used function
+ *                Use uart1 interface to transfer one char
+ * Parameters   : uint8 TxChar - character to tx
+ * Returns      : OK
+*******************************************************************************/
+ STATUS uart_tx_one_char(uint8 uart, uint8 TxChar)
+{
+    while (true){
+        uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
+        if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
+            break;
+        }
+    }
+    WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
+    return OK;
+}
+
+void uart_set_txto() {
+	_intFlags |= UART_TXFIFO_EMPTY_INT_ENA;
+
+	uart_rx_intr_enable(UART0);
+}
+
+void uart_clear_txto() {
+	uart_rx_intr_disable(UART0);
+
+	_intFlags &= ~(UART_TXFIFO_EMPTY_INT_ENA);
+
+	uart_rx_intr_enable(UART0);
+}
+
+
+/******************************************************************************
+ * FunctionName : uart0_tx_buffer
+ * Description  : use uart0 to transfer buffer
+ * Parameters   : uint8 *buf - point to send buffer
+ *                uint16 len - buffer len
+ * Returns      :
+*******************************************************************************/
+void ICACHE_FLASH_ATTR
+uart0_tx_buffer(uint8 *buf, uint16 len)
+{
+    uint16 i;
+    for (i = 0; i < len; i++)
+    {
+        uart_tx_one_char(UART0, buf[i]);
+    }
+}
+
+/******************************************************************************
+ * FunctionName : uart0_sendStr
+ * Description  : use uart0 to transfer buffer
+ * Parameters   : uint8 *buf - point to send buffer
+ *                uint16 len - buffer len
+ * Returns      :
+*******************************************************************************/
+void ICACHE_FLASH_ATTR
+uart0_sendStr(const char *str)
+{
+    while(*str){
+        uart_tx_one_char(UART0, *str++);
+    }
+}
+
+void uart_rx_flush() {
+  volatile uint8 byte;
+
+  uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)
+	  & UART_RXFIFO_CNT;
+
+	while((fifo_len--) > 0) {
+	  byte = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
+	}
+}
+
+/******************************************************************************
+ * FunctionName : uart0_rx_intr_handler
+ * Description  : Internal used function
+ *                UART0 interrupt handler, add self handle code inside
+ * Parameters   : void *para - point to ETS_UART_INTR_ATTACH's arg
+ * Returns      : NONE
+*******************************************************************************/
+LOCAL void
+uart0_rx_intr_handler(void *para)
+{
+	uint32 intMask = 0, recv = 0;
+	uint8_t uart_no = UART0;
+	
+    /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
+    * uart1 and uart0 respectively
+    */
+    //uint8 RcvChar;
+    //uint8 uart_no = UART0;//UartDev.buff_uart_no;
+    //uint8 fifo_len = 0;
+    //uint8 buf_idx = 0;
+    //uint8 temp,cnt;
+    //RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
+    
+    	/*ATTENTION:*/
+	/*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
+	/*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
+	/*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */
+    if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)){
+        WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
+    }
+		else if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){
+				recv = 1;
+				intMask = UART_RXFIFO_FULL_INT_CLR;
+
+
+        //system_os_post(uart_recvTaskPrio, 0, 0);
+    }
+		else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)){
+				recv = 1;
+				intMask = UART_RXFIFO_TOUT_INT_CLR;
+
+        //system_os_post(uart_recvTaskPrio, 0, 0);
+    }
+		else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)){
+			CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
+      
+			_intFlags &= ~(UART_TXFIFO_EMPTY_INT_ENA);
+
+			system_os_post(UART_TASK_PRIORITY, UART_SIG_TXTO, 0);
+      WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);
+        
+    }
+		else if(UART_RXFIFO_OVF_INT_ST  == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)){
+        WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR);
+    }
+
+	if(recv) {
+		//Grab data from FIFO
+		uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)
+			& UART_RXFIFO_CNT;
+
+		while((fifo_len--) > 0) {
+			//uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
+			//RingBuffer_addByte((RingBuffer*)&_rxBuffer, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF);
+      _rxBuffer[_rxLen++] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
+		}
+
+		//Clear int flag
+		WRITE_PERI_REG(UART_INT_CLR(UART0), intMask);
+
+    //Post receive message
+    system_os_post(UART_TASK_PRIORITY, UART_SIG_RECV, 0);
+	}
+}
+
+/******************************************************************************
+ * FunctionName : uart_init
+ * Description  : user interface for init uart
+ * Parameters   : UartBautRate uart0_br - uart0 bautrate
+ *                UartBautRate uart1_br - uart1 bautrate
+ * Returns      : NONE
+*******************************************************************************/
+void ICACHE_FLASH_ATTR
+uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
+{
+    /*this is a example to process uart data from task,please change the priority to fit your application task if exists*/
+    //system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen);  //demo with a task to process the uart data
+    
+		//RingBuffer_init((RingBuffer*)&_rxBuffer);
+    _rxLen = 0;
+
+		_intFlags = UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_OVF_INT_ENA|UART_RXFIFO_TOUT_INT_ENA;
+
+    UartDev.baut_rate = uart0_br;
+    uart_config(UART0);
+    
+		UartDev.baut_rate = uart1_br;
+    uart_config(UART1);
+    
+		ETS_UART_INTR_ENABLE();
+    
+
+    /*option 1: use default print, output from uart0 , will wait some time if fifo is full */
+    //do nothing...
+
+    /*option 2: output from uart1,uart1 output will not wait , just for output debug info */
+    /*os_printf output uart data via uart1(GPIO2)*/
+    //os_install_putc1((void *)uart1_write_char);    //use this one to output debug information via uart1 //
+
+    /*option 3: output from uart0 will skip current byte if fifo is full now... */
+    /*see uart0_write_char_no_wait:you can output via a buffer or output directly */
+    /*os_printf output uart data via uart0 or uart buffer*/
+    //os_install_putc1((void *)uart0_write_char_no_wait);  //use this to print via uart0
+}
+
+/******************************************************************************
+ * FunctionName : uart_tx_one_char_no_wait
+ * Description  : uart tx a single char without waiting for fifo 
+ * Parameters   : uint8 uart - uart port
+ *                uint8 TxChar - char to tx
+ * Returns      : STATUS
+*******************************************************************************/
+STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar)
+{
+    uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
+    if (fifo_cnt < 126) {
+        WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
+    }
+    return OK;
+}
+
+STATUS uart0_tx_one_char_no_wait(uint8 TxChar)
+{
+    uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
+    if (fifo_cnt < 126) {
+        WRITE_PERI_REG(UART_FIFO(UART0) , TxChar);
+    }
+    return OK;
+}
+
+uint16 uart0_send_nowait(uint8 *buffer, uint16 len) {
+	uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
+
+	uint8 written = 0;
+
+	if(fifo_cnt < 126) {
+		uint8 avail = 126 - fifo_cnt;
+		if(avail > len)
+			avail = len;
+
+		written = avail;
+
+		while( (avail--) > 0 ) {
+			WRITE_PERI_REG(UART_FIFO(UART0), *(buffer++));
+		}
+	}
+
+	return written;
+}
+
+
+/******************************************************************************
+ * FunctionName : uart1_sendStr_no_wait
+ * Description  : uart tx a string without waiting for every char, used for print debug info which can be lost
+ * Parameters   : const char *str - string to be sent
+ * Returns      : NONE
+*******************************************************************************/
+void uart1_sendStr_no_wait(const char *str)
+{
+    while(*str){
+        uart_tx_one_char_no_wait(UART1, *str++);
+    }
+}
+
+
+void uart_rx_intr_disable(uint8 uart_no)
+{
+    CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), _intFlags);
+}
+
+void uart_rx_intr_enable(uint8 uart_no)
+{
+    SET_PERI_REG_MASK(UART_INT_ENA(uart_no), _intFlags);
+}
+
+
+void ICACHE_FLASH_ATTR
+UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len) 
+{
+    SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_BIT_NUM,len,UART_BIT_NUM_S);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num) 
+{
+    SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_STOP_BIT_NUM,bit_num,UART_STOP_BIT_NUM_S);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask) 
+{
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK);
+    SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetParity(uint8 uart_no, UartParityMode Parity_mode) 
+{
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY |UART_PARITY_EN);
+    if(Parity_mode==NONE_BITS){
+    }else{
+        SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode|UART_PARITY_EN);
+    }
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetBaudrate(uint8 uart_no,uint32 baud_rate)
+{
+    uart_div_modify(uart_no, UART_CLK_FREQ /baud_rate);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh)
+{
+    if(flow_ctrl&USART_HardwareFlowControl_RTS){
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
+        SET_PERI_REG_BITS(UART_CONF1(uart_no),UART_RX_FLOW_THRHD,rx_thresh,UART_RX_FLOW_THRHD_S);
+        SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
+    }else{
+        CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
+    }
+    if(flow_ctrl&USART_HardwareFlowControl_CTS){
+        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS);
+        SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
+    }else{
+        CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
+    }
+}
+
+void ICACHE_FLASH_ATTR
+UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us) //do not use if tx flow control enabled
+{
+    uint32 t_s = system_get_time();
+    while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)){
+		
+        if(( system_get_time() - t_s )> time_out_us){
+            break;
+        }
+	WRITE_PERI_REG(0X60000914, 0X73);//WTD
+
+    }
+}
+
+void ICACHE_FLASH_ATTR
+UART_ResetFifo(uint8 uart_no)
+{
+    SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
+    CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
+}
+
+void ICACHE_FLASH_ATTR
+UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask)
+{
+    WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask);
+}
+
+void ICACHE_FLASH_ATTR
+UART_SetIntrEna(uint8 uart_no,uint32 ena_mask)
+{
+    SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask);
+}
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.h
new file mode 100644
index 000000000..3f9fff514
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart.h
@@ -0,0 +1,208 @@
+/*
+ * File	: uart.h
+ * Copyright (C) 2013 - 2016, Espressif Systems
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef UART_APP_H
+#define UART_APP_H
+
+#include "uart_register.h"
+#include "eagle_soc.h"
+#include "c_types.h"
+
+#define UART0   0
+#define UART1   1
+
+#define UART_SIG_RECV		0x01
+#define UART_SIG_TXTO		0x02
+#define UART_TASK_PRIORITY	2
+
+typedef enum {
+    FIVE_BITS = 0x0,
+    SIX_BITS = 0x1,
+    SEVEN_BITS = 0x2,
+    EIGHT_BITS = 0x3
+} UartBitsNum4Char;
+
+typedef enum {
+    ONE_STOP_BIT             = 0x1,
+    ONE_HALF_STOP_BIT        = 0x2,
+    TWO_STOP_BIT             = 0x3
+} UartStopBitsNum;
+
+typedef enum {
+    NONE_BITS = 0x2,
+    ODD_BITS   = 1,
+    EVEN_BITS = 0
+} UartParityMode;
+
+typedef enum {
+    STICK_PARITY_DIS   = 0,
+    STICK_PARITY_EN    = 1
+} UartExistParity;
+
+typedef enum {
+    UART_None_Inverse = 0x0,
+    UART_Rxd_Inverse = UART_RXD_INV,
+    UART_CTS_Inverse = UART_CTS_INV,
+    UART_Txd_Inverse = UART_TXD_INV,
+    UART_RTS_Inverse = UART_RTS_INV,
+} UART_LineLevelInverse;
+
+
+typedef enum {
+    BIT_RATE_300 = 300,
+    BIT_RATE_600 = 600,
+    BIT_RATE_1200 = 1200,
+    BIT_RATE_2400 = 2400,
+    BIT_RATE_4800 = 4800,
+    BIT_RATE_9600   = 9600,
+    BIT_RATE_19200  = 19200,
+    BIT_RATE_38400  = 38400,
+    BIT_RATE_57600  = 57600,
+    BIT_RATE_74880  = 74880,
+    BIT_RATE_115200 = 115200,
+    BIT_RATE_230400 = 230400,
+    BIT_RATE_460800 = 460800,
+    BIT_RATE_921600 = 921600,
+    BIT_RATE_1843200 = 1843200,
+    BIT_RATE_3686400 = 3686400,
+} UartBautRate;
+
+typedef enum {
+    NONE_CTRL,
+    HARDWARE_CTRL,
+    XON_XOFF_CTRL
+} UartFlowCtrl;
+
+typedef enum {
+    USART_HardwareFlowControl_None = 0x0,
+    USART_HardwareFlowControl_RTS = 0x1,
+    USART_HardwareFlowControl_CTS = 0x2,
+    USART_HardwareFlowControl_CTS_RTS = 0x3
+} UART_HwFlowCtrl;
+
+typedef enum {
+    EMPTY,
+    UNDER_WRITE,
+    WRITE_OVER
+} RcvMsgBuffState;
+
+typedef struct {
+    uint32     RcvBuffSize;
+    uint8     *pRcvMsgBuff;
+    uint8     *pWritePos;
+    uint8     *pReadPos;
+    uint8      TrigLvl; //JLU: may need to pad
+    RcvMsgBuffState  BuffState;
+} RcvMsgBuff;
+
+typedef struct {
+    uint32   TrxBuffSize;
+    uint8   *pTrxBuff;
+} TrxMsgBuff;
+
+typedef enum {
+    BAUD_RATE_DET,
+    WAIT_SYNC_FRM,
+    SRCH_MSG_HEAD,
+    RCV_MSG_BODY,
+    RCV_ESC_CHAR,
+} RcvMsgState;
+
+typedef struct {
+    UartBautRate 	     baut_rate;
+    UartBitsNum4Char  data_bits;
+    UartExistParity      exist_parity;
+    UartParityMode 	    parity;    
+    UartStopBitsNum   stop_bits;
+    UartFlowCtrl         flow_ctrl;
+    RcvMsgBuff          rcv_buff;
+    TrxMsgBuff           trx_buff;
+    RcvMsgState        rcv_state;
+    int                      received;
+    int                      buff_uart_no;  //indicate which uart use tx/rx buffer
+} UartDevice;
+
+void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
+void uart0_sendStr(const char *str);
+uint16 uart0_send_nowait(uint8 *buffer, uint16 len);
+void uart_set_txto();
+void uart_clear_txto();
+
+
+///////////////////////////////////////
+#define UART_FIFO_LEN  128  //define the tx fifo length
+#define UART_TX_EMPTY_THRESH_VAL 0x10
+
+
+ struct UartBuffer{
+    uint32     UartBuffSize;
+    uint8     *pUartBuff;
+    uint8     *pInPos;
+    uint8     *pOutPos;
+    STATUS  BuffState;
+    uint16    Space;  //remanent space of the buffer
+    uint8  TcpControl;
+    struct  UartBuffer     *  nextBuff;
+};
+
+struct UartRxBuff{
+    uint32     UartRxBuffSize;
+    uint8     *pUartRxBuff;
+    uint8     *pWritePos;
+    uint8     *pReadPos;
+    STATUS RxBuffState;
+    uint32    Space;  //remanent space of the buffer
+} ;
+
+typedef enum {
+    RUN = 0,
+    BLOCK = 1,
+} TCPState;
+
+//void ICACHE_FLASH_ATTR uart_test_rx();
+STATUS uart_tx_one_char(uint8 uart, uint8 TxChar);
+STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar);
+void  uart1_sendStr_no_wait(const char *str);
+struct UartBuffer*  Uart_Buf_Init();
+
+
+void  uart_rx_intr_enable(uint8 uart_no);
+void  uart_rx_intr_disable(uint8 uart_no);
+void uart0_tx_buffer(uint8 *buf, uint16 len);
+uint16 uart_get(uint8 *out, uint16 len);
+void uart_rx_flush();
+
+//==============================================
+#define FUNC_UART0_CTS 4
+#define FUNC_U0CTS                      4
+#define FUNC_U1TXD_BK                   2
+#define UART_LINE_INV_MASK  (0x3f<<19)
+void UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len);
+void UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num);
+void UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask);
+void UART_SetParity(uint8 uart_no, UartParityMode Parity_mode);
+void UART_SetBaudrate(uint8 uart_no,uint32 baud_rate);
+void UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh);
+void UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us); //do not use if tx flow control enabled
+void UART_ResetFifo(uint8 uart_no);
+void UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask);
+void UART_SetIntrEna(uint8 uart_no,uint32 ena_mask);
+void UART_SetPrintPort(uint8 uart_no);
+bool UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us);
+//==============================================
+
+#endif
+
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart_register.h b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart_register.h
new file mode 100644
index 000000000..05f6ceaf2
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/uart_register.h
@@ -0,0 +1,156 @@
+/*
+ * File	: uart_register.h
+ * Copyright (C) 2013 - 2016, Espressif Systems
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 3 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+ *  Copyright (c) 2010 - 2011 Espressif System
+ *
+ */
+
+#ifndef UART_REGISTER_H_
+#define UART_REGISTER_H_
+
+#define REG_UART_BASE(i)                (0x60000000 + (i)*0xf00)
+//version value:32'h062000
+
+#define UART_FIFO(i)                    (REG_UART_BASE(i) + 0x0)
+#define UART_RXFIFO_RD_BYTE                 0x000000FF
+#define UART_RXFIFO_RD_BYTE_S               0
+
+#define UART_INT_RAW(i)                 (REG_UART_BASE(i) + 0x4)
+#define UART_RXFIFO_TOUT_INT_RAW            (BIT(8))
+#define UART_BRK_DET_INT_RAW                (BIT(7))
+#define UART_CTS_CHG_INT_RAW                (BIT(6))
+#define UART_DSR_CHG_INT_RAW                (BIT(5))
+#define UART_RXFIFO_OVF_INT_RAW             (BIT(4))
+#define UART_FRM_ERR_INT_RAW                (BIT(3))
+#define UART_PARITY_ERR_INT_RAW             (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_RAW           (BIT(1))
+#define UART_RXFIFO_FULL_INT_RAW            (BIT(0))
+
+#define UART_INT_ST(i)                  (REG_UART_BASE(i) + 0x8)
+#define UART_RXFIFO_TOUT_INT_ST             (BIT(8))
+#define UART_BRK_DET_INT_ST                 (BIT(7))
+#define UART_CTS_CHG_INT_ST                 (BIT(6))
+#define UART_DSR_CHG_INT_ST                 (BIT(5))
+#define UART_RXFIFO_OVF_INT_ST              (BIT(4))
+#define UART_FRM_ERR_INT_ST                 (BIT(3))
+#define UART_PARITY_ERR_INT_ST              (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_ST            (BIT(1))
+#define UART_RXFIFO_FULL_INT_ST             (BIT(0))
+
+#define UART_INT_ENA(i)                 (REG_UART_BASE(i) + 0xC)
+#define UART_RXFIFO_TOUT_INT_ENA            (BIT(8))
+#define UART_BRK_DET_INT_ENA                (BIT(7))
+#define UART_CTS_CHG_INT_ENA                (BIT(6))
+#define UART_DSR_CHG_INT_ENA                (BIT(5))
+#define UART_RXFIFO_OVF_INT_ENA             (BIT(4))
+#define UART_FRM_ERR_INT_ENA                (BIT(3))
+#define UART_PARITY_ERR_INT_ENA             (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_ENA           (BIT(1))
+#define UART_RXFIFO_FULL_INT_ENA            (BIT(0))
+
+#define UART_INT_CLR(i)                 (REG_UART_BASE(i) + 0x10)
+#define UART_RXFIFO_TOUT_INT_CLR            (BIT(8))
+#define UART_BRK_DET_INT_CLR                (BIT(7))
+#define UART_CTS_CHG_INT_CLR                (BIT(6))
+#define UART_DSR_CHG_INT_CLR                (BIT(5))
+#define UART_RXFIFO_OVF_INT_CLR             (BIT(4))
+#define UART_FRM_ERR_INT_CLR                (BIT(3))
+#define UART_PARITY_ERR_INT_CLR             (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_CLR           (BIT(1))
+#define UART_RXFIFO_FULL_INT_CLR            (BIT(0))
+
+#define UART_CLKDIV(i)                  (REG_UART_BASE(i) + 0x14)
+#define UART_CLKDIV_CNT                     0x000FFFFF
+#define UART_CLKDIV_S                       0
+
+#define UART_AUTOBAUD(i)                (REG_UART_BASE(i) + 0x18)
+#define UART_GLITCH_FILT                    0x000000FF
+#define UART_GLITCH_FILT_S                  8
+#define UART_AUTOBAUD_EN                    (BIT(0))
+
+#define UART_STATUS(i)                  (REG_UART_BASE(i) + 0x1C)
+#define UART_TXD                            (BIT(31))
+#define UART_RTSN                           (BIT(30))
+#define UART_DTRN                           (BIT(29))
+#define UART_TXFIFO_CNT                     0x000000FF
+#define UART_TXFIFO_CNT_S                   16
+#define UART_RXD                            (BIT(15))
+#define UART_CTSN                           (BIT(14))
+#define UART_DSRN                           (BIT(13))
+#define UART_RXFIFO_CNT                     0x000000FF
+#define UART_RXFIFO_CNT_S                   0
+
+#define UART_CONF0(i)                   (REG_UART_BASE(i) + 0x20)
+#define UART_DTR_INV                        (BIT(24))
+#define UART_RTS_INV                        (BIT(23))
+#define UART_TXD_INV                        (BIT(22))
+#define UART_DSR_INV                        (BIT(21))
+#define UART_CTS_INV                        (BIT(20))
+#define UART_RXD_INV                        (BIT(19))
+#define UART_TXFIFO_RST                     (BIT(18))
+#define UART_RXFIFO_RST                     (BIT(17))
+#define UART_IRDA_EN                        (BIT(16))
+#define UART_TX_FLOW_EN                     (BIT(15))
+#define UART_LOOPBACK                       (BIT(14))
+#define UART_IRDA_RX_INV                    (BIT(13))
+#define UART_IRDA_TX_INV                    (BIT(12))
+#define UART_IRDA_WCTL                      (BIT(11))
+#define UART_IRDA_TX_EN                     (BIT(10))
+#define UART_IRDA_DPLX                      (BIT(9))
+#define UART_TXD_BRK                        (BIT(8))
+#define UART_SW_DTR                         (BIT(7))
+#define UART_SW_RTS                         (BIT(6))
+#define UART_STOP_BIT_NUM                   0x00000003
+#define UART_STOP_BIT_NUM_S                 4
+#define UART_BIT_NUM                        0x00000003
+#define UART_BIT_NUM_S                      2
+#define UART_PARITY_EN                      (BIT(1))
+#define UART_PARITY_EN_M                0x00000001
+#define UART_PARITY_EN_S                 1
+#define UART_PARITY                         (BIT(0))
+#define UART_PARITY_M                       0x00000001
+#define UART_PARITY_S                        0
+
+#define UART_CONF1(i)                   (REG_UART_BASE(i) + 0x24)
+#define UART_RX_TOUT_EN                     (BIT(31))
+#define UART_RX_TOUT_THRHD                  0x0000007F
+#define UART_RX_TOUT_THRHD_S                24
+#define UART_RX_FLOW_EN                     (BIT(23))
+#define UART_RX_FLOW_THRHD                  0x0000007F
+#define UART_RX_FLOW_THRHD_S                16
+#define UART_TXFIFO_EMPTY_THRHD             0x0000007F
+#define UART_TXFIFO_EMPTY_THRHD_S           8
+#define UART_RXFIFO_FULL_THRHD              0x0000007F
+#define UART_RXFIFO_FULL_THRHD_S            0
+
+#define UART_LOWPULSE(i)                (REG_UART_BASE(i) + 0x28)
+#define UART_LOWPULSE_MIN_CNT               0x000FFFFF
+#define UART_LOWPULSE_MIN_CNT_S             0
+
+#define UART_HIGHPULSE(i)               (REG_UART_BASE(i) + 0x2C)
+#define UART_HIGHPULSE_MIN_CNT              0x000FFFFF
+#define UART_HIGHPULSE_MIN_CNT_S            0
+
+#define UART_PULSE_NUM(i)               (REG_UART_BASE(i) + 0x30)
+#define UART_PULSE_NUM_CNT                  0x0003FF
+#define UART_PULSE_NUM_CNT_S                0
+
+#define UART_DATE(i)                    (REG_UART_BASE(i) + 0x78)
+#define UART_ID(i)                      (REG_UART_BASE(i) + 0x7C)
+
+#endif // UART_REGISTER_H_INCLUDED
+
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/user_main.c b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/user_main.c
new file mode 100644
index 000000000..d53d48ff1
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/temp/user_main.c
@@ -0,0 +1,452 @@
+#include <string.h>
+#include "ets_sys.h"
+#include "osapi.h"
+#include "gpio.h"
+#include "os_type.h"
+#include "user_config.h"
+#include "driver/uart.h"
+#include "user_interface.h"
+#include "espconn.h"
+#include <mem.h>
+
+#define NETWORK_UPDATE_RATE	5
+
+#define user_procTaskQueueLen    1
+
+
+#define BAUD	921600
+
+#define TCP_PORT	8080
+
+#define AP_CHANNEL	6
+#define AP_MAX_CONNECTIONS	4
+#define AP_SSID	"MicroCART"
+#define AP_PSK	"m1cr0cart"
+
+#define AP_GATEWAY	"192.168.1.1"
+#define AP_NETMASK	"255.255.255.0"
+
+#define DHCP_IP_START	"192.168.1.10"
+#define DHCP_IP_END		"192.168.1.15"
+
+#define TCP_MAX_PACKET_SIZE		1460
+#define UART_TX_BUFFER_SIZE		(TCP_MAX_PACKET_SIZE * 14)
+#define TCP_SEND_BUFFER_SIZE	(TCP_MAX_PACKET_SIZE * 6)
+
+#define TCP_MAX_SEND	(500)
+
+static volatile uint8 *_txBuffer;
+static volatile uint16 _txBufferSize;
+static volatile uint16 _txBufferLen;
+static volatile uint8 _tcpRecvHold = 0;
+static volatile int _tcpHoldCount = -10;
+
+//TCP send
+static volatile int _tcpSendActive = 0;
+static volatile uint8 *_tcpSendBuffer;
+static volatile uint16 _tcpSendBufferLen = 0;
+
+//static volatile char *_messageBuffer;
+
+static struct espconn tcpServerConn;
+static struct espconn *tcpClient = NULL;
+
+os_event_t    user_procTaskQueue[user_procTaskQueueLen];
+static void uart_task(os_event_t *events);
+
+static volatile os_timer_t networkTimer;
+static volatile uint8 _ledSet;
+
+static void startServer();
+
+static void wifi_handler(System_Event_t *event);
+static void tcp_connect_handler(void *arg);
+static void tcp_disconnect_handler(void *arg);
+static void tcp_recv_handler(void *arg, char *data, unsigned short len);
+static void tcp_sent_handler(void *arg);
+static void tcp_write_handler(void *arg);
+
+static int tcpSend(uint8 *data, uint8 len);
+static int tcpSendSome();
+
+
+void network_task(void *arg) {
+	static uint8_t ledState = 0;
+	
+	if(_ledSet) {
+		ledState = 1;
+		_ledSet = 0;
+
+		//Turn on activity LED
+		gpio_output_set(BIT0, 0, BIT0, 0);
+	}
+
+	if(ledState) {
+		if(ledState++ > 10) {
+			ledState = 0;
+			gpio_output_set(0, BIT0, BIT0, 0);
+		}
+	}
+
+	//Verify that there's no data "stuck" in the TCP send buffer
+	if(tcpClient != NULL && !_tcpSendActive && _tcpSendBufferLen > 0) {
+		//Let's send some
+		if(tcpSendSome() > 0) {
+			_tcpSendActive = 1;
+		}
+	}
+}
+
+//Task to process events
+static void ICACHE_FLASH_ATTR
+uart_task(os_event_t *events)
+{
+    switch(events->sig) {
+		case UART_SIG_RECV: {
+			//uint8 data[128];
+
+			//Set the activity LED
+			_ledSet = 1;
+
+			//Echo data
+			//int count = uart_get((char*)data, sizeof(data));
+			int count = uart_get((char*)(_tcpSendBuffer + _tcpSendBufferLen),
+				TCP_SEND_BUFFER_SIZE - _tcpSendBufferLen);
+			
+			_tcpSendBufferLen += count;
+
+			//Send over TCP
+			if(tcpClient != NULL && !_tcpSendActive) {
+				_tcpSendActive = 1;
+
+				tcpSendSome();
+			}
+		}
+    break;
+		
+		case UART_SIG_TXTO:
+			//Transmit FIFO near empty
+
+			if(_txBufferLen > 0) {
+				//Fill the FIFO
+				uint16 sent = uart0_send_nowait((uint8*)_txBuffer, _txBufferLen);
+
+				if(sent < _txBufferLen) {
+					memmove((uint8*)_txBuffer, (uint8*)_txBuffer + sent,
+						_txBufferLen - sent);
+					_txBufferLen -= sent;
+
+					uart_set_txto();
+				}
+				else {
+					_txBufferLen = 0;
+					uart_clear_txto();
+				}
+
+				//Check if receive hold is active
+				if((_tcpRecvHold == 1) && (tcpClient != NULL) &&
+					((_txBufferSize - _txBufferLen) >= (10*TCP_MAX_PACKET_SIZE)) ) {
+					espconn_recv_unhold(tcpClient);
+					_tcpRecvHold = 0;
+
+					_tcpHoldCount--;
+				}
+			}
+		break;
+
+    default:
+      os_delay_us(10);
+      break;
+    }
+
+		//os_delay_us(100);
+}
+
+void wifi_init() {
+	//Set to SoftAP mode
+	wifi_set_opmode(SOFTAP_MODE);
+
+	//SoftAP configuration
+	struct softap_config apConfig = {
+		.channel = AP_CHANNEL,
+		.authmode = AUTH_WPA2_PSK,
+		.ssid_hidden = 0,
+		.max_connection = AP_MAX_CONNECTIONS,
+		.beacon_interval = 100
+	};
+	strcpy(apConfig.ssid, AP_SSID);
+	strcpy(apConfig.password, AP_PSK);
+	apConfig.ssid_len = strlen(AP_SSID);
+
+	//Set configuration
+	wifi_softap_set_config(&apConfig);
+
+	//Disable power saving mode
+	//This seems to help reduce jitter in latency
+	//wifi_set_sleep_type(NONE_SLEEP_T);
+
+	//DHCP configuration
+	struct dhcps_lease dhcpLease = {
+		.start_ip = ipaddr_addr(DHCP_IP_START),
+		.end_ip = ipaddr_addr(DHCP_IP_END)
+	};
+
+	//Disable DHCP server while making changes
+	wifi_softap_dhcps_stop();
+	wifi_softap_set_dhcps_lease(&dhcpLease);
+
+	//Set IP info
+	struct ip_info ipInfo = {
+		.ip = ipaddr_addr(AP_GATEWAY),
+		.gw = ipaddr_addr(AP_GATEWAY),
+		.netmask = ipaddr_addr(AP_NETMASK)
+	};
+	wifi_set_ip_info(SOFTAP_IF, &ipInfo);
+	
+	//Restart DHCP server
+	wifi_softap_dhcps_start();
+
+	//Set WiFi event handler
+	wifi_set_event_handler_cb(&wifi_handler);
+
+	startServer();
+}
+
+void startServer() {
+	//Configure TCP server
+	tcpServerConn.type = ESPCONN_TCP;
+	tcpServerConn.state = ESPCONN_NONE;
+	tcpServerConn.proto.tcp = (esp_tcp*)os_malloc(sizeof(esp_tcp));
+	tcpServerConn.proto.tcp->local_port = TCP_PORT;
+
+	espconn_regist_connectcb(&tcpServerConn, &tcp_connect_handler);
+
+	tcpClient = NULL;
+
+	//Start TCP server
+	espconn_accept(&tcpServerConn);
+
+	//Set maximum connection count
+	espconn_tcp_set_max_con(1);
+}
+
+void wifi_handler(System_Event_t *event) {
+	switch(event->event) {
+		case EVENT_SOFTAPMODE_STACONNECTED:
+			//TODO: Perhaps do something with this information
+		break;
+
+		case EVENT_SOFTAPMODE_STADISCONNECTED:
+			//TODO: Maybe do something here?
+		break;
+
+		default:
+			break;
+	}
+}
+
+void tcp_connect_handler(void *arg) {
+	struct espconn *conn = (struct espconn*)arg;
+	
+	espconn_regist_disconcb(conn, &tcp_disconnect_handler);
+	espconn_regist_recvcb(conn, &tcp_recv_handler);
+	espconn_regist_sentcb(conn, &tcp_sent_handler);
+	espconn_regist_write_finish(conn, &tcp_write_handler);
+	
+	//Set socket options
+	espconn_set_opt(conn, ESPCONN_NODELAY | ESPCONN_REUSEADDR | ESPCONN_KEEPALIVE | ESPCONN_COPY);
+
+	tcpClient = conn;
+	_tcpRecvHold = 0;
+
+	_tcpSendActive = 0;
+	_tcpSendBufferLen = 0;
+}
+
+void tcp_disconnect_handler(void *arg) {
+	tcpClient = NULL;
+
+	char msg[128];
+	os_sprintf("tcp_disconnect_handler: %d\r\n", (int)_tcpSendBufferLen);
+	uart0_send_nowait(msg, strlen(msg));
+
+	_tcpSendBufferLen = 0;
+	_tcpSendActive = 0;
+}
+
+void tcp_recv_handler(void *arg, char *data, unsigned short len) {
+	//Send over UART
+	
+	//Copy into UART tx buffer
+	if( (_txBufferLen + len) > _txBufferSize ) {
+		//Yikes!
+		espconn_recv_hold((struct espconn*)arg);
+		_tcpRecvHold = 1;
+	}
+	else {
+		if(_txBufferLen == 0) {
+			//Software buffer is empty
+
+			//Put as much as possible into FIFO
+			uint16 sent = uart0_send_nowait(data, len);
+
+			if(sent < len) {
+				//Put the rest in the software buffer
+				memcpy((uint8*)_txBuffer, data + sent, len - sent);
+				_txBufferLen = len - sent;
+				uart_set_txto();
+			}
+		}
+		else {
+			//Just copy all of the data into the software buffer
+			memcpy((uint8*)_txBuffer + _txBufferLen, data, len);
+			_txBufferLen += len;
+			uart_set_txto();
+		}
+
+		if( (_tcpRecvHold == 0) &&
+			(_txBufferSize - _txBufferLen) < (10*TCP_MAX_PACKET_SIZE) ) {
+			//If we can't fit another packet into the software buffer
+			//Temporarily disable receiving
+			espconn_recv_hold((struct espconn*)arg);
+			_tcpRecvHold = 1;
+
+			_tcpHoldCount++;
+			
+		}
+	}
+
+
+	_ledSet = 1;
+}
+
+int tcpSendSome() {
+	if(_tcpSendBufferLen == 0) {
+		return 0;
+	}
+	else if(tcpClient == NULL) {
+		return 0;
+	}
+	
+	uint16 sendAmt = (_tcpSendBufferLen < TCP_MAX_SEND) ? (_tcpSendBufferLen) : (TCP_MAX_SEND);
+
+	sint8 retval = espconn_sent(tcpClient, (uint8*)_tcpSendBuffer, sendAmt);
+
+	if(retval != 0) {
+		/*
+		char buffer[128];
+		char *msg;
+
+		if(retval == ESPCONN_MEM) {
+			msg = "[Error] espconn_sent returned ESPCONN_MEM\r\n";
+		}
+		else if(retval == ESPCONN_ARG) {
+			msg = "[Error] espconn_sent returned ESPCONN_ARG\r\n";
+		}
+		else {
+			os_sprintf(buffer, "[Error] espconn_sent returned an unknown error: %d\r\n", (int)retval);
+			msg = buffer;
+		}
+		uart0_send_nowait(msg, strlen(msg));
+		
+		
+		char msg[128];
+		os_sprintf("tcpSendSome: Failed to send (%d)\r\n", (int)_tcpSendBufferLen);
+		uart0_send_nowait(msg, strlen(msg));
+		*/
+		//Error, nothing was sent
+		return 0;
+	}
+	else {
+		//Remove the sent data from the buffer
+		memmove((uint8*)_tcpSendBuffer, (uint8*)_tcpSendBuffer + sendAmt, (uint16)_tcpSendBufferLen - sendAmt);
+		_tcpSendBufferLen -= sendAmt;
+/*
+		char msg[128];
+		os_sprintf("tcpSendSome: Sent %d (%d left)\r\n", (int)sendAmt, (int)_tcpSendBufferLen);
+		uart0_send_nowait(msg, strlen(msg));
+*/
+		return sendAmt;
+	}
+}
+
+void tcp_sent_handler(void *arg) {
+	//Nothing to do here
+	char msg[128];
+	os_sprintf(msg, "tcp_sent_handler: %d, %d\r\n", (int)_tcpSendActive, (int)_tcpSendBufferLen);
+	uart0_send_nowait(msg, strlen(msg));
+}
+
+void tcp_write_handler(void *arg) {
+	if(tcpClient == NULL) {
+		return;
+	}
+
+	//Debug stuff
+	char msg[128];
+	os_sprintf(msg, "tcp_write_handler: %d, %d\r\n", (int)_tcpSendActive, (int)_tcpSendBufferLen);
+	uart0_send_nowait(msg, strlen(msg));
+
+	if(_tcpSendBufferLen > 0) {
+		//Send some more
+		int sent = tcpSendSome();
+
+		if(sent == 0 || _tcpSendBufferLen == 0) {
+			_tcpSendActive = 0;
+		}
+	}
+	else {
+		_tcpSendActive = 0;
+	}
+}
+
+//Init function 
+void ICACHE_FLASH_ATTR
+user_init()
+{
+    //Remove debug statements from UART0
+    system_set_os_print(0);
+		
+		// Initialize the GPIO subsystem.
+    gpio_init();
+
+    //Set GPIO2 to output mode
+    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
+
+    //Set GPIO2 low
+    gpio_output_set(0, BIT0, BIT0, 0);
+
+		//Initialize UART
+		uart_init(BAUD, BAUD);
+
+		//Initialize UART TX buffer
+		_txBuffer = (uint8*)os_malloc(UART_TX_BUFFER_SIZE);
+		_txBufferSize = UART_TX_BUFFER_SIZE;
+		_txBufferLen = 0;
+
+		//Initialize TCP send buffer
+		_tcpSendBuffer = (uint8*)os_malloc(TCP_SEND_BUFFER_SIZE);
+		_tcpSendBufferLen = 0;
+		_tcpSendActive = 0;
+
+		//Initialize WiFi
+		wifi_init();
+
+		//Start TCP server
+		startServer();
+
+		_ledSet = 0;
+
+    //Disarm timer
+    os_timer_disarm(&networkTimer);
+
+    //Setup timer
+    os_timer_setfn(&networkTimer, (os_timer_func_t *)network_task, NULL);
+
+    //Arm the timer
+    os_timer_arm(&networkTimer, NETWORK_UPDATE_RATE, 1);
+    
+    //Start os task
+    system_os_task(uart_task, UART_TASK_PRIORITY,user_procTaskQueue,
+			user_procTaskQueueLen);
+}
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_main.c b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_main.c
new file mode 100644
index 000000000..4c1da44e5
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_main.c
@@ -0,0 +1,275 @@
+#include <string.h>
+#include "ets_sys.h"
+#include "osapi.h"
+#include "gpio.h"
+#include "os_type.h"
+#include "user_config.h"
+#include "driver/uart.h"
+#include "user_interface.h"
+#include "espconn.h"
+#include "user_tcp.h"
+#include <mem.h>
+
+#define NETWORK_UPDATE_RATE	5
+
+#define user_procTaskQueueLen    10
+
+
+#define BAUD	921600
+
+#define TCP_PORT	8080
+
+#define AP_CHANNEL	6
+#define AP_MAX_CONNECTIONS	4
+#define AP_SSID	"MicroCART"
+#define AP_PSK	"m1cr0cart"
+
+#define AP_GATEWAY	"192.168.1.1"
+#define AP_NETMASK	"255.255.255.0"
+
+#define DHCP_IP_START	"192.168.1.10"
+#define DHCP_IP_END		"192.168.1.15"
+
+#define UART_RX_BUFFER_SIZE		(1024)
+#define UART_TX_BUFFER_SIZE		(128)
+
+static uint8 *_rxBuffer;
+static uint8 *_txBuffer;
+
+os_event_t    user_procTaskQueue[user_procTaskQueueLen];
+static void uart_task(os_event_t *events);
+static void tcp_recvHandler(uint16 len);
+
+static volatile os_timer_t networkTimer;
+static volatile uint8 _ledSet;
+
+static void wifi_handler(System_Event_t *event);
+
+static volatile int uartCount = 0;
+static volatile uint8 _uartTxFlag;
+
+void network_task(void *arg) {
+	static uint8_t ledState = 0;
+	
+	if(_ledSet) {
+		ledState = 1;
+		_ledSet = 0;
+
+		//Turn on activity LED
+		gpio_output_set(BIT0, 0, BIT0, 0);
+	}
+
+	if(ledState) {
+		if(ledState++ > 10) {
+			ledState = 0;
+			gpio_output_set(0, BIT0, BIT0, 0);
+		}
+	}
+
+/*
+	static int i = 0;
+	if(i == 0) {
+		i = 100;
+
+		char msg[128];
+		os_sprintf(msg, "[Heap] %d\r\n", 
+			(int)system_get_free_heap_size());
+		uart_debugSend(msg);
+	}
+	i--;
+*/
+}
+
+//Task to process events
+//static void ICACHE_FLASH_ATTR
+static void uart_task(os_event_t *events)
+{
+    switch(events->sig) {
+		case UART_SIG_ERR_FRM: {
+			uart_debugSend("UART RX Frame error\r\n");
+		}
+		break;
+
+		case UART_SIG_ERR_PARITY: {
+			uart_debugSend("UART RX Parity error\r\n");
+		}
+		break;
+
+		case UART_SIG_RXOVF: {
+			uart_debugSend("UART RX overflow\r\n");
+		}
+		case UART_SIG_RECV: {
+			static int bytesRecv = 0;
+
+			//Set the activity LED
+			_ledSet = 1;
+
+			//Echo data
+			int count = uart_get((char*)_rxBuffer, UART_RX_BUFFER_SIZE);
+
+			bytesRecv += count;
+			
+			if(count > 0) {
+				tcp_send((uint8*)_rxBuffer, count);
+
+				uartCount = 0;
+
+			}
+		}
+    break;
+
+
+		
+		case UART_SIG_TXTO: {
+			//Transmit FIFO near empty
+
+			//Grab as much as we can send
+			uint8 sendSpace = uart_getTxFifoAvail();
+			uint8 toSend = tcp_receive(_txBuffer, sendSpace);
+
+			if(toSend > 0) {
+				//Fill the FIFO
+				uart0_send_nowait(_txBuffer, toSend);
+
+				uart_set_txto();
+				_ledSet = 1;
+			}
+			else {
+				uart_clear_txto();
+
+				_uartTxFlag = 0;
+			}
+		}
+		break;
+
+    default:
+      //os_delay_us(10);
+      break;
+    }
+
+		//os_delay_us(100);
+}
+
+void wifi_init() {
+	//Set to SoftAP mode
+	wifi_set_opmode(SOFTAP_MODE);
+
+	//SoftAP configuration
+	struct softap_config apConfig = {
+		.channel = AP_CHANNEL,
+		.authmode = AUTH_WPA2_PSK,
+		.ssid_hidden = 0,
+		.max_connection = AP_MAX_CONNECTIONS,
+		.beacon_interval = 100
+	};
+	strcpy(apConfig.ssid, AP_SSID);
+	strcpy(apConfig.password, AP_PSK);
+	apConfig.ssid_len = strlen(AP_SSID);
+
+	//Set configuration
+	wifi_softap_set_config(&apConfig);
+
+	//Disable power saving mode
+	//This seems to help reduce jitter in latency
+	//wifi_set_sleep_type(NONE_SLEEP_T);
+
+	//DHCP configuration
+	struct dhcps_lease dhcpLease = {
+		.start_ip = ipaddr_addr(DHCP_IP_START),
+		.end_ip = ipaddr_addr(DHCP_IP_END)
+	};
+
+	//Disable DHCP server while making changes
+	wifi_softap_dhcps_stop();
+	wifi_softap_set_dhcps_lease(&dhcpLease);
+
+	//Set IP info
+	struct ip_info ipInfo = {
+		.ip = ipaddr_addr(AP_GATEWAY),
+		.gw = ipaddr_addr(AP_GATEWAY),
+		.netmask = ipaddr_addr(AP_NETMASK)
+	};
+	wifi_set_ip_info(SOFTAP_IF, &ipInfo);
+	
+	//Restart DHCP server
+	wifi_softap_dhcps_start();
+
+	//Set WiFi event handler
+	wifi_set_event_handler_cb(&wifi_handler);
+}
+
+void wifi_handler(System_Event_t *event) {
+	switch(event->event) {
+		case EVENT_SOFTAPMODE_STACONNECTED:
+			//TODO: Perhaps do something with this information
+		break;
+
+		case EVENT_SOFTAPMODE_STADISCONNECTED:
+			//TODO: Maybe do something here?
+		break;
+
+		default:
+			break;
+	}
+}
+
+void tcp_recvHandler(uint16 len) {
+	if(_uartTxFlag == 0) {
+		//Grab as much as we can currently send
+		uint8 sendSpace = uart_getTxFifoAvail();
+		uint8 toSend = tcp_receive(_txBuffer, sendSpace);
+
+		uart0_send_nowait(_txBuffer, toSend);
+		uart_set_txto();
+
+		_uartTxFlag = 1;
+		_ledSet = 1;
+	}
+}
+
+//Init function 
+void ICACHE_FLASH_ATTR
+user_init()
+{
+    //Remove debug statements from UART0
+    system_set_os_print(0);
+		
+		// Initialize the GPIO subsystem.
+    gpio_init();
+
+    //Set GPIO2 to output mode
+    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
+
+    //Set GPIO2 low
+    gpio_output_set(0, BIT0, BIT0, 0);
+
+		//Initialize UART
+		uart_init(BAUD, BAUD);
+
+		_rxBuffer = (uint8*)os_malloc(UART_RX_BUFFER_SIZE);
+		_txBuffer = (uint8*)os_malloc(UART_TX_BUFFER_SIZE);
+
+		_uartTxFlag = 0;
+
+		//Initialize WiFi
+		wifi_init();
+
+		//Start TCP server
+		tcp_start(TCP_PORT);
+		tcp_setRecvHandler(&tcp_recvHandler);
+
+		_ledSet = 0;
+
+    //Disarm timer
+    os_timer_disarm(&networkTimer);
+
+    //Setup timer
+    os_timer_setfn(&networkTimer, (os_timer_func_t *)network_task, NULL);
+
+    //Arm the timer
+    os_timer_arm(&networkTimer, NETWORK_UPDATE_RATE, 1);
+    
+    //Start os task
+    system_os_task(uart_task, UART_TASK_PRIORITY,user_procTaskQueue,
+			user_procTaskQueueLen);
+}
diff --git a/wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_tcp.c b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_tcp.c
new file mode 100644
index 000000000..615a86a0e
--- /dev/null
+++ b/wifi_bridge/ESP8266_Wifi-Serial-Adapter/user/user_tcp.c
@@ -0,0 +1,301 @@
+#include "user_tcp.h"
+
+#include "ip_addr.h"
+#include "osapi.h"
+#include "espconn.h"
+#include "os_type.h"
+#include <mem.h>
+#include <string.h>
+
+//Debugging
+#include "driver/uart.h"
+
+#define TCP_MAX_PACKET	(1460)
+#define TCP_SEND_BUFFER_SIZE	(1024 * 20)
+#define TCP_RECV_BUFFER_SIZE	(10*TCP_MAX_PACKET)
+
+#define TCP_RECV_HOLD_LIMIT	(5*TCP_MAX_PACKET)
+#define TCP_TIMEOUT		(7200)
+
+#define MAX_SEND_COUNT	(2)
+
+struct Connection {
+	struct espconn *pConn;
+
+	uint8 *sendBuffer;
+	uint16 sendSize, sendLen;
+
+	uint8 *recvBuffer;
+	uint16 recvSize, recvLen;
+	uint8 recvHold;
+
+	ReceiveHandler recvHandler;
+
+	int sendCount;
+};
+
+static struct espconn _tcpServer;
+
+static struct Connection _tcpConn;
+
+static volatile os_timer_t _sendTimer;
+
+//Callbacks
+static void __connectHandler(void *arg);
+static void __disconnectHandler(void *arg);
+static void __reconnectHandler(void *arg, sint8 err);
+static void __recvHandler(void *arg, char *data, unsigned short len);
+static void __sentHandler(void *arg);
+static void __writeHandler(void *arg);
+
+static void __sendTimerHandler(void *arg);
+
+static uint16 __send(struct Connection *conn, uint8 *data, uint16 len);
+
+
+void tcp_start(uint16 port) {
+	os_timer_disarm(&_sendTimer);
+	os_timer_setfn(&_sendTimer, (os_timer_func_t*)__sendTimerHandler, NULL);
+
+	_tcpConn.sendBuffer = (uint8*)os_malloc(TCP_SEND_BUFFER_SIZE);
+	_tcpConn.sendSize = TCP_SEND_BUFFER_SIZE;
+	_tcpConn.sendLen = 0;
+
+	_tcpConn.recvBuffer = (uint8*)os_malloc(TCP_RECV_BUFFER_SIZE);
+	_tcpConn.recvSize = TCP_RECV_BUFFER_SIZE;
+	_tcpConn.recvLen = 0;
+	_tcpConn.recvHold = 0;
+
+	_tcpConn.pConn = NULL;
+
+	_tcpServer.type = ESPCONN_TCP;
+	_tcpServer.state = ESPCONN_NONE;
+	_tcpServer.proto.tcp = (esp_tcp*)os_malloc(sizeof(esp_tcp));
+	_tcpServer.proto.tcp->local_port = port;
+	
+	espconn_regist_connectcb(&_tcpServer, &__connectHandler);
+	espconn_regist_time(&_tcpServer, TCP_TIMEOUT, ESPCONN_KEEPINTVL);
+
+	espconn_accept(&_tcpServer);
+	espconn_tcp_set_max_con(1);
+}
+
+void tcp_stop() {
+	//TODO
+}
+
+void tcp_setRecvHandler(ReceiveHandler handler) {
+	_tcpConn.recvHandler = handler;
+}
+
+void tcp_send(uint8* buffer, uint16 len) {
+	if(len == 0) {
+		uart_debugSend("[tcp_send] Given buffer length 0\r\n");
+		
+		return;
+	}
+
+	if(_tcpConn.pConn != NULL) {
+		if((_tcpConn.sendCount < MAX_SEND_COUNT) && (_tcpConn.sendLen == 0)) {
+			uint16 sendAmt = __send(&_tcpConn, buffer, len);
+
+			if(sendAmt < len) {
+				if((sendAmt + _tcpConn.sendLen) > _tcpConn.sendSize) {
+					uart_debugSend("[tcp_send] send buffer full!\r\n");
+				}
+				else {
+					memcpy(_tcpConn.sendBuffer, buffer + sendAmt, len - sendAmt);
+					_tcpConn.sendLen = len - sendAmt;
+				}
+			}
+		}
+		else {
+			if((_tcpConn.sendLen + len) > _tcpConn.sendSize) {
+				uart_debugSend("[tcp_send] send buffer full!\r\n");
+			}
+			else {
+				memcpy(_tcpConn.sendBuffer + _tcpConn.sendLen, buffer, len);
+				_tcpConn.sendLen += len;
+			}
+
+			//char msg[128];
+			//os_sprintf(msg, "[tcp_send] Defferred (%d)\r\n", (int)_tcpConn.sendLen);
+			//__debug(msg);
+		}
+	}
+	else {
+		uart_debugSend("[Send] (Not connected)\r\n");
+	}
+}
+
+uint16 tcp_receive(uint8 *buffer, uint16 size) {
+	uint16 recvAmt = _tcpConn.recvLen;
+	if(recvAmt > size)
+		recvAmt = size;
+	
+	memcpy(buffer, _tcpConn.recvBuffer, recvAmt);
+
+	if(recvAmt != _tcpConn.recvLen) {
+		memmove(_tcpConn.recvBuffer, _tcpConn.recvBuffer + recvAmt, (_tcpConn.recvLen - recvAmt));
+	}
+
+	_tcpConn.recvLen -= recvAmt;
+
+	if( (_tcpConn.recvHold == 1) && (_tcpConn.recvLen < TCP_RECV_HOLD_LIMIT) ) {
+		espconn_recv_unhold(_tcpConn.pConn);
+		_tcpConn.recvHold = 0;
+	}
+
+	return recvAmt;
+}
+
+uint16 __send(struct Connection *conn, uint8 *data, uint16 len) {
+	//conn->sendCount++;
+
+	uint16 sendAmt = len;
+	if(sendAmt > TCP_MAX_PACKET)
+		sendAmt = TCP_MAX_PACKET;
+
+
+	if(conn->pConn == NULL) {
+		uart_debugSend("[__send] NULL espconn\r\n");
+
+		return 0;
+	}
+	
+	sint8 retval = espconn_send(conn->pConn, data, sendAmt);
+/*
+	char msg[128];
+	os_sprintf(msg, "[__send] Sent %d\r\n", (int)sendAmt);
+	uart_debugSend(msg);
+*/	
+
+	if((retval != 0) && (conn->sendCount == 0)) {
+		os_timer_arm(&_sendTimer, 1, 0);
+	}
+
+	if(retval == ESPCONN_ARG) {
+		char msg[128];
+		os_sprintf(msg, "[__send] ESPCONN_ARG: %d, %d\r\n", (int)data, (int)sendAmt);
+		uart_debugSend(msg);
+
+		return 0;
+	}
+	else if(retval != 0) {
+		char msg[128];
+		os_sprintf(msg, "[__send] (%d, %d)\r\n", (int)retval, (int)(conn->sendCount));
+		uart_debugSend(msg);
+
+		sendAmt = 0;
+	}
+	else {
+		//char msg[128];
+		//os_sprintf(msg, "[__send] %d sent\r\n", (int)sendAmt);
+		//uart_debugSend(msg);
+
+		conn->sendCount++;
+	}
+
+	return sendAmt;
+}
+
+void __connectHandler(void *arg) {
+	struct espconn *conn = (struct espconn*)arg;
+
+	_tcpConn.pConn = conn;
+	conn->reverse = &_tcpConn;
+	_tcpConn.sendLen = 0;
+
+	//Register handlers
+	espconn_regist_disconcb(conn, &__disconnectHandler);
+	espconn_regist_reconcb(conn, &__reconnectHandler);
+	espconn_regist_recvcb(conn, &__recvHandler);
+	espconn_regist_sentcb(conn, &__sentHandler);
+	espconn_regist_write_finish(conn, &__writeHandler);
+	espconn_regist_time(conn, TCP_TIMEOUT, ESPCONN_KEEPINTVL);
+
+
+	//Set socket options
+	espconn_set_opt(conn, ESPCONN_NODELAY | ESPCONN_COPY);
+
+	//Clear tcpConn structure
+	//RingBuffer_clear(&(_tcpConn.sendBuffer));
+	_tcpConn.sendCount = 0;
+}
+
+void __disconnectHandler(void *arg) {
+	struct Connection *conn = (struct Connection*)(((struct espconn*)arg)->reverse);
+
+	conn->pConn = NULL;
+
+	uart_debugSend("[Disconnect]\r\n");
+}
+
+void __reconnectHandler(void *arg, sint8 err) {
+	char msg[128];
+
+	os_sprintf(msg, "[Reconnect] (%d)\r\n", (int)err);
+	uart_debugSend(msg);
+}
+
+void __recvHandler(void *arg, char *data, unsigned short len) {
+	struct Connection *conn = (struct Connection*)(((struct espconn*)arg)->reverse);
+	
+	memcpy(conn->recvBuffer + conn->recvLen, data, len);
+	conn->recvLen += len;
+
+	if( (conn->recvLen > TCP_RECV_HOLD_LIMIT) && (conn->recvHold == 0) ) {
+		espconn_recv_hold(conn->pConn);
+		conn->recvHold = 1;
+	}
+
+	if(conn->recvHandler != NULL) {
+		conn->recvHandler(len);
+	}
+}
+
+void __sentHandler(void *arg) {
+	struct Connection *conn = (struct Connection*)(((struct espconn*)arg)->reverse);
+	
+	conn->sendCount--;
+
+/*
+	char msg[128];
+	os_sprintf(msg, "[__sentHandler] %d\r\n", (int)conn->sendCount);
+	uart_debugSend(msg);
+*/
+
+	if((conn->sendCount < MAX_SEND_COUNT) && (conn->sendLen > 0)) {
+		uint16 sendAmt = __send(conn, conn->sendBuffer, conn->sendLen);
+		
+		if(sendAmt != 0) {
+			if(sendAmt != conn->sendLen) {
+				memmove(conn->sendBuffer, conn->sendBuffer + sendAmt,
+					conn->sendLen - sendAmt);
+			}
+			conn->sendLen -= sendAmt;
+		}
+
+		//char msg[128];
+		//os_sprintf(msg, "[sentHandler] Sent %d (%d)\r\n", (int)sendAmt, (int)conn->sendLen);
+		//__debug(msg);
+	}
+}
+
+void __writeHandler(void *arg) {
+	struct Connection *conn = (struct Connection*)(((struct espconn*)arg)->reverse);
+}
+
+void __sendTimerHandler(void *arg) {
+	if((_tcpConn.sendCount < MAX_SEND_COUNT) && (_tcpConn.sendLen > 0)) {
+		uint16 sendAmt = __send(&_tcpConn, _tcpConn.sendBuffer, _tcpConn.sendLen);
+
+		if(sendAmt != 0) {
+			if(sendAmt != _tcpConn.sendLen) {
+				memmove(_tcpConn.sendBuffer, _tcpConn.sendBuffer + sendAmt,
+					_tcpConn.sendLen - sendAmt);
+			}
+			_tcpConn.sendLen -= sendAmt;
+		}
+	}
+}
-- 
GitLab