kopia lustrzana https://github.com/martin-ger/esp_mqtt
Initial commit
commit
930f3e9ff5
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.mingw.base.1187134800">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.mingw.base.1187134800" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.mingw.base.1187134800" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.mingw.base.1187134800.1389533387" name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.mingw.base.1439189001" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.base">
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.PE" id="cdt.managedbuild.target.gnu.platform.mingw.base.1397325870" name="Debug Platform" osList="win32" superClass="cdt.managedbuild.target.gnu.platform.mingw.base"/>
|
||||
<builder arguments="-f ${ProjDirPath}/Makefile" command="mingw32-make.exe" id="cdt.managedbuild.builder.gnu.cross.1675187259" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.mingw.base.1317942365" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.811380737" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1098370265" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1774344183" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base">
|
||||
<option id="gnu.cpp.compiler.option.include.paths.1171001356" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""C:\Espressif\ESP8266_SDK\include\""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1783416175" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.base.270886552" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.base">
|
||||
<option id="gnu.c.compiler.option.include.paths.452661071" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""C:\Espressif\ESP8266_SDK\include\""/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1963428165" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.base.466053609" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base.748040064" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.base">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.581028506" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="at_v0.19_on_SDKv0.9.2.null.2072922048" name="at_v0.19_on_SDKv0.9.2"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Default">
|
||||
<resource resourceType="PROJECT" workspacePath="/at_v0.19_on_SDKv0.9.2"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1187134800;cdt.managedbuild.toolchain.gnu.mingw.base.1187134800.1389533387;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.1774344183;cdt.managedbuild.tool.gnu.cpp.compiler.input.1783416175">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1187134800;cdt.managedbuild.toolchain.gnu.mingw.base.1187134800.1389533387;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.270886552;cdt.managedbuild.tool.gnu.c.compiler.input.1963428165">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
|
||||
<buildTargets>
|
||||
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make.exe</buildCommand>
|
||||
<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
|
||||
<buildTarget>all</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make.exe</buildCommand>
|
||||
<buildArguments>-f ${ProjDirPath}/Makefile clean</buildArguments>
|
||||
<buildTarget>clean</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>false</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
<target name="flash" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
|
||||
<buildCommand>mingw32-make.exe</buildCommand>
|
||||
<buildArguments>-f ${ProjDirPath}/Makefile</buildArguments>
|
||||
<buildTarget>flash</buildTarget>
|
||||
<stopOnError>true</stopOnError>
|
||||
<useDefaultCommand>true</useDefaultCommand>
|
||||
<runAllBuilders>true</runAllBuilders>
|
||||
</target>
|
||||
</buildTargets>
|
||||
</storageModule>
|
||||
</cproject>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>mqtt_pub</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,159 @@
|
|||
# Changelog
|
||||
# Changed the variables to include the header file directory
|
||||
# Added global var for the XTENSA tool root
|
||||
#
|
||||
# This make file still needs some work.
|
||||
#
|
||||
#
|
||||
# Output directors to store intermediate compiled files
|
||||
# relative to the project directory
|
||||
BUILD_BASE = build
|
||||
FW_BASE = firmware
|
||||
FLAVOR = release
|
||||
#FLAVOR = debug
|
||||
|
||||
# Base directory for the compiler
|
||||
XTENSA_TOOLS_ROOT ?= c:/Espressif/xtensa-lx106-elf/bin
|
||||
|
||||
# base directory of the ESP8266 SDK package, absolute
|
||||
SDK_BASE ?= c:/Espressif/ESP8266_SDK
|
||||
|
||||
#Esptool.py path and port
|
||||
PYTHON ?= C:\Python27\python.exe
|
||||
ESPTOOL ?= c:\Espressif\utils\esptool.py
|
||||
ESPPORT ?= COM2
|
||||
|
||||
# name for the target project
|
||||
TARGET = app
|
||||
|
||||
# which modules (subdirectories) of the project to include in compiling
|
||||
MODULES = driver user
|
||||
EXTRA_INCDIR = include $(SDK_BASE)/../include
|
||||
|
||||
# libraries used in this project, mainly provided by the SDK
|
||||
LIBS = c gcc hal phy pp net80211 lwip wpa upgrade main ssl
|
||||
|
||||
# compiler flags using during compilation of source files
|
||||
CFLAGS = -Os -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
|
||||
|
||||
ifeq ($(FLAVOR),debug)
|
||||
CFLAGS += -g -O2
|
||||
LDFLAGS += -g -O2
|
||||
endif
|
||||
|
||||
ifeq ($(FLAVOR),release)
|
||||
CFLAGS += -g -O0
|
||||
LDFLAGS += -g -O0
|
||||
endif
|
||||
|
||||
# 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 = 0x00000
|
||||
FW_FILE_1_ARGS = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
|
||||
FW_FILE_2 = 0x40000
|
||||
FW_FILE_2_ARGS = -es .irom0.text $@ -ec
|
||||
|
||||
# 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
|
||||
####
|
||||
FW_TOOL ?= $(XTENSA_TOOLS_ROOT)/esptool
|
||||
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).bin)
|
||||
FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_FILE_2).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 clean
|
||||
|
||||
all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2)
|
||||
|
||||
$(FW_FILE_1): $(TARGET_OUT)
|
||||
$(vecho) "FW $@"
|
||||
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)
|
||||
|
||||
$(FW_FILE_2): $(TARGET_OUT)
|
||||
$(vecho) "FW $@"
|
||||
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_2_ARGS)
|
||||
|
||||
$(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 $@
|
||||
|
||||
firmware:
|
||||
$(Q) mkdir -p $@
|
||||
|
||||
flash: firmware/0x00000.bin firmware/0x40000.bin
|
||||
$(PYTHON) $(ESPTOOL) -p $(ESPPORT) write_flash 0x00000 firmware/0x00000.bin 0x40000 firmware/0x40000.bin
|
||||
|
||||
test: flash
|
||||
screen $(ESPPORT) 115200
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
clean:
|
||||
$(Q) rm -f $(APP_AR)
|
||||
$(Q) rm -f $(TARGET_OUT)
|
||||
$(Q) rm -rf $(BUILD_DIR)
|
||||
$(Q) rm -rf $(BUILD_BASE)
|
||||
$(Q) rm -f $(FW_FILE_1)
|
||||
$(Q) rm -f $(FW_FILE_2)
|
||||
$(Q) rm -rf $(FW_BASE)
|
||||
|
||||
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))
|
|
@ -0,0 +1,144 @@
|
|||
# Changelog
|
||||
# Changed the variables to include the header file directory
|
||||
# Added global var for the XTENSA tool root
|
||||
#
|
||||
# This make file still needs some work.
|
||||
#
|
||||
#
|
||||
# Output directors to store intermediate compiled files
|
||||
# relative to the project directory
|
||||
BUILD_BASE = build
|
||||
FW_BASE = firmware
|
||||
|
||||
# Base directory for the compiler
|
||||
XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
|
||||
|
||||
# base directory of the ESP8266 SDK package, absolute
|
||||
SDK_BASE ?= /opt/Espressif/ESP8266_SDK
|
||||
|
||||
#Esptool.py path and port
|
||||
ESPTOOL ?= esptool.py
|
||||
ESPPORT ?= /dev/ttyUSB0
|
||||
|
||||
# name for the target project
|
||||
TARGET = app
|
||||
|
||||
# which modules (subdirectories) of the project to include in compiling
|
||||
MODULES = driver user
|
||||
EXTRA_INCDIR = include $(SDK_BASE)/../include
|
||||
|
||||
# libraries used in this project, mainly provided by the SDK
|
||||
LIBS = c gcc hal phy pp net80211 lwip wpa upgrade main ssl
|
||||
|
||||
# compiler flags using during compilation of source files
|
||||
CFLAGS = -Os -g -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 = 0x00000
|
||||
FW_FILE_1_ARGS = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
|
||||
FW_FILE_2 = 0x40000
|
||||
FW_FILE_2_ARGS = -es .irom0.text $@ -ec
|
||||
|
||||
# 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
|
||||
####
|
||||
FW_TOOL ?= /usr/bin/esptool
|
||||
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).bin)
|
||||
FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_FILE_2).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 clean
|
||||
|
||||
all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2)
|
||||
|
||||
$(FW_FILE_1): $(TARGET_OUT)
|
||||
$(vecho) "FW $@"
|
||||
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)
|
||||
|
||||
$(FW_FILE_2): $(TARGET_OUT)
|
||||
$(vecho) "FW $@"
|
||||
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_2_ARGS)
|
||||
|
||||
$(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 $@
|
||||
|
||||
firmware:
|
||||
$(Q) mkdir -p $@
|
||||
|
||||
flash: firmware/0x00000.bin firmware/0x40000.bin
|
||||
$(ESPTOOL) --port $(ESPPORT) write_flash 0x00000 firmware/0x00000.bin 0x40000 firmware/0x40000.bin
|
||||
|
||||
test: flash
|
||||
screen $(ESPPORT) 115200
|
||||
|
||||
clean:
|
||||
$(Q) rm -f $(APP_AR)
|
||||
$(Q) rm -f $(TARGET_OUT)
|
||||
$(Q) rm -rf $(BUILD_DIR)
|
||||
$(Q) rm -rf $(BUILD_BASE)
|
||||
$(Q) rm -f $(FW_FILE_1)
|
||||
$(Q) rm -f $(FW_FILE_2)
|
||||
$(Q) rm -rf $(FW_BASE)
|
||||
|
||||
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))
|
|
@ -0,0 +1,159 @@
|
|||
# Changelog
|
||||
# Changed the variables to include the header file directory
|
||||
# Added global var for the XTENSA tool root
|
||||
#
|
||||
# This make file still needs some work.
|
||||
#
|
||||
#
|
||||
# Output directors to store intermediate compiled files
|
||||
# relative to the project directory
|
||||
BUILD_BASE = build
|
||||
FW_BASE = firmware
|
||||
FLAVOR = release
|
||||
#FLAVOR = debug
|
||||
|
||||
# Base directory for the compiler
|
||||
XTENSA_TOOLS_ROOT ?= c:/Espressif/xtensa-lx106-elf/bin
|
||||
|
||||
# base directory of the ESP8266 SDK package, absolute
|
||||
SDK_BASE ?= c:/Espressif/ESP8266_SDK
|
||||
|
||||
#Esptool.py path and port
|
||||
PYTHON ?= C:\Python27\python.exe
|
||||
ESPTOOL ?= c:\Espressif\utils\esptool.py
|
||||
ESPPORT ?= COM2
|
||||
|
||||
# name for the target project
|
||||
TARGET = app
|
||||
|
||||
# which modules (subdirectories) of the project to include in compiling
|
||||
MODULES = driver user
|
||||
EXTRA_INCDIR = include $(SDK_BASE)/../include
|
||||
|
||||
# libraries used in this project, mainly provided by the SDK
|
||||
LIBS = c gcc hal phy pp net80211 lwip wpa upgrade main
|
||||
|
||||
# compiler flags using during compilation of source files
|
||||
CFLAGS = -Os -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
|
||||
|
||||
ifeq ($(FLAVOR),debug)
|
||||
CFLAGS += -g -O2
|
||||
LDFLAGS += -g -O2
|
||||
endif
|
||||
|
||||
ifeq ($(FLAVOR),release)
|
||||
CFLAGS += -g -O0
|
||||
LDFLAGS += -g -O0
|
||||
endif
|
||||
|
||||
# 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 = 0x00000
|
||||
FW_FILE_1_ARGS = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
|
||||
FW_FILE_2 = 0x40000
|
||||
FW_FILE_2_ARGS = -es .irom0.text $@ -ec
|
||||
|
||||
# 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
|
||||
####
|
||||
FW_TOOL ?= $(XTENSA_TOOLS_ROOT)/esptool
|
||||
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).bin)
|
||||
FW_FILE_2 := $(addprefix $(FW_BASE)/,$(FW_FILE_2).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 clean
|
||||
|
||||
all: checkdirs $(TARGET_OUT) $(FW_FILE_1) $(FW_FILE_2)
|
||||
|
||||
$(FW_FILE_1): $(TARGET_OUT)
|
||||
$(vecho) "FW $@"
|
||||
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_1_ARGS)
|
||||
|
||||
$(FW_FILE_2): $(TARGET_OUT)
|
||||
$(vecho) "FW $@"
|
||||
$(Q) $(FW_TOOL) -eo $(TARGET_OUT) $(FW_FILE_2_ARGS)
|
||||
|
||||
$(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 $@
|
||||
|
||||
firmware:
|
||||
$(Q) mkdir -p $@
|
||||
|
||||
flash: firmware/0x00000.bin firmware/0x40000.bin
|
||||
$(PYTHON) $(ESPTOOL) -p $(ESPPORT) write_flash 0x00000 firmware/0x00000.bin 0x40000 firmware/0x40000.bin
|
||||
|
||||
test: flash
|
||||
screen $(ESPPORT) 115200
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
clean:
|
||||
$(Q) rm -f $(APP_AR)
|
||||
$(Q) rm -f $(TARGET_OUT)
|
||||
$(Q) rm -rf $(BUILD_DIR)
|
||||
$(Q) rm -rf $(BUILD_BASE)
|
||||
$(Q) rm -f $(FW_FILE_1)
|
||||
$(Q) rm -f $(FW_FILE_2)
|
||||
$(Q) rm -rf $(FW_BASE)
|
||||
|
||||
$(foreach bdir,$(BUILD_DIR),$(eval $(call compile-objects,$(bdir))))
|
|
@ -0,0 +1,157 @@
|
|||
**esp_mqtt**
|
||||
==========
|
||||
This is MQTT client library for ESP8266, port from: [MQTT client library for Contiki](https://github.com/esar/contiki-mqtt)
|
||||
|
||||
**Features:**
|
||||
|
||||
* Support subscribing, publishing, authentication, will messages, keep alive pings and all 3 QoS levels (it should be a fully functional client).
|
||||
* Support multiple connection (to multiple hosts).
|
||||
* **Support SSL connection (max 1024 bit key size)**
|
||||
* Easy to setup and use
|
||||
|
||||
|
||||
|
||||
**Usage**
|
||||
```c
|
||||
#include "ets_sys.h"
|
||||
#include "driver/uart.h"
|
||||
#include "osapi.h"
|
||||
#include "mqtt.h"
|
||||
#include "wifi.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "gpio.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
MQTT_Client mqttClient;
|
||||
|
||||
void wifiConnectCb(uint8_t status)
|
||||
{
|
||||
if(status == STATION_GOT_IP){
|
||||
MQTT_Connect(&mqttClient);
|
||||
|
||||
MQTT_Subscribe(&mqttClient, "/test/topic");
|
||||
MQTT_Subscribe(&mqttClient, "/test2/topic");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
void mqttConnectedCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
INFO("MQTT: Connected\r\n");
|
||||
}
|
||||
|
||||
void mqttDisconnectedCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
INFO("MQTT: Disconnected\r\n");
|
||||
}
|
||||
void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh)
|
||||
{
|
||||
INFO("MQTT topic: %s, data: %s \r\n", topic, data);
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
os_delay_us(1000000);
|
||||
|
||||
CFG_Load();
|
||||
|
||||
MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, SEC_SSL);
|
||||
MQTT_InitClient(&mqttClient, sysCfg.device_id, sysCfg.mqtt_user, sysCfg.mqtt_pass, sysCfg.mqtt_keepalive);
|
||||
MQTT_OnConnected(&mqttClient, mqttConnectedCb);
|
||||
MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);
|
||||
MQTT_OnData(&mqttClient, mqttDataCb);
|
||||
|
||||
WIFI_Connect(sysCfg.sta_ssid, sysCfg.sta_pwd, wifiConnectCb);
|
||||
|
||||
INFO("\r\nSystem started ...\r\n");
|
||||
}
|
||||
```
|
||||
**Default configuration**
|
||||
See: *user_config.h* and *config.c*
|
||||
**Create SSL Self sign**
|
||||
```
|
||||
openssl req -x509 -newkey rsa:1024 -keyout key.pem -out cert.pem -days XXX
|
||||
```
|
||||
**SSL Mqtt broker for test**
|
||||
```javascript
|
||||
var mosca = require('mosca')
|
||||
var SECURE_KEY = __dirname + '/key.pem';
|
||||
var SECURE_CERT = __dirname + '/cert.pem';
|
||||
var ascoltatore = {
|
||||
//using ascoltatore
|
||||
type: 'mongo',
|
||||
url: 'mongodb://localhost:27017/mqtt',
|
||||
pubsubCollection: 'ascoltatori',
|
||||
mongo: {}
|
||||
};
|
||||
|
||||
var moscaSettings = {
|
||||
port: 8440,
|
||||
stats: false,
|
||||
backend: ascoltatore,
|
||||
persistence: {
|
||||
factory: mosca.persistence.Mongo,
|
||||
url: 'mongodb://localhost:27017/mqtt'
|
||||
},
|
||||
secure : {
|
||||
keyPath: SECURE_KEY,
|
||||
certPath: SECURE_CERT,
|
||||
port: 8443
|
||||
}
|
||||
};
|
||||
|
||||
var server = new mosca.Server(moscaSettings);
|
||||
server.on('ready', setup);
|
||||
|
||||
server.on('clientConnected', function(client) {
|
||||
console.log('client connected', client.id);
|
||||
});
|
||||
|
||||
// fired when a message is received
|
||||
server.on('published', function(packet, client) {
|
||||
console.log('Published', packet.payload);
|
||||
});
|
||||
|
||||
// fired when the mqtt server is ready
|
||||
function setup() {
|
||||
console.log('Mosca server is up and running')
|
||||
}
|
||||
```
|
||||
|
||||
**Be careful:** This library is not fully supported for too long messages.
|
||||
**Status:** *Alpha release.*
|
||||
|
||||
[MQTT Broker for test](https://github.com/mcollina/mosca)
|
||||
[MQTT Client for test](https://chrome.google.com/webstore/detail/mqttlens/hemojaaeigabkbcookmlgmdigohjobjm?hl=en)
|
||||
|
||||
**Contributing:**
|
||||
|
||||
***Feel free to contribute to the project in any way you like!***
|
||||
|
||||
**Requried:**
|
||||
|
||||
esp_iot_sdk_v0.9.4_14_12_19
|
||||
|
||||
**Authors:**
|
||||
[Tuan PM](https://twitter.com/TuanPMT)
|
||||
|
||||
**Donations**
|
||||
|
||||
Invite me to a coffee
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=JR9RVLFC4GE6J)
|
||||
|
||||
|
||||
**LICENSE - "MIT License"**
|
||||
|
||||
Copyright (c) 2014-2015 Tuan PM, https://twitter.com/TuanPMT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
#############################################################
|
||||
# Required variables for each makefile
|
||||
# Discard this section from all parent makefiles
|
||||
# Expected variables (with automatic defaults):
|
||||
# CSRCS (all "C" files in the dir)
|
||||
# SUBDIRS (all subdirs with a Makefile)
|
||||
# GEN_LIBS - list of libs to be generated ()
|
||||
# GEN_IMAGES - list of images to be generated ()
|
||||
# COMPONENTS_xxx - a list of libs/objs in the form
|
||||
# subdir/lib to be extracted and rolled up into
|
||||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libdriver.a
|
||||
endif
|
||||
|
||||
|
||||
#############################################################
|
||||
# Configuration i.e. compile options etc.
|
||||
# Target specific stuff (defines etc.) goes in here!
|
||||
# Generally values applying to a tree are captured in the
|
||||
# makefile at its root level - these are then overridden
|
||||
# for a subtree within the makefile rooted therein
|
||||
#
|
||||
#DEFINES +=
|
||||
|
||||
#############################################################
|
||||
# Recursion Magic - Don't touch this!!
|
||||
#
|
||||
# Each subtree potentially has an include directory
|
||||
# corresponding to the common APIs applicable to modules
|
||||
# rooted at that subtree. Accordingly, the INCLUDE PATH
|
||||
# of a module can only contain the include directories up
|
||||
# its parent path, and not its siblings
|
||||
#
|
||||
# Required for each makefile to inherit from the parent
|
||||
#
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
INCLUDES += -I ./
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
/******************************************************************************
|
||||
* Copyright 2013-2014 Espressif Systems (Wuxi)
|
||||
*
|
||||
* FileName: uart.c
|
||||
*
|
||||
* Description: Two UART mode configration and interrupt handler.
|
||||
* Check your hardware connection while use this mode.
|
||||
*
|
||||
* Modification history:
|
||||
* 2014/3/12, v1.0 create this file.
|
||||
*******************************************************************************/
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "driver/uart.h"
|
||||
#include "osapi.h"
|
||||
#include "driver/uart_register.h"
|
||||
//#include "ssc.h"
|
||||
|
||||
|
||||
// UartDev is defined and initialized in rom code.
|
||||
extern UartDevice UartDev;
|
||||
//extern os_event_t at_recvTaskQueue[at_recvTaskQueueLen];
|
||||
|
||||
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
|
||||
{
|
||||
/* rcv_buff size if 0x100 */
|
||||
ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff));
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
|
||||
}
|
||||
|
||||
uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));
|
||||
|
||||
WRITE_PERI_REG(UART_CONF0(uart_no), UartDev.exist_parity
|
||||
| UartDev.parity
|
||||
| (UartDev.stop_bits << UART_STOP_BIT_NUM_S)
|
||||
| (UartDev.data_bits << 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);
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
|
||||
|
||||
//set rx fifo trigger
|
||||
// WRITE_PERI_REG(UART_CONF1(uart_no),
|
||||
// ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
|
||||
// ((96 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) |
|
||||
// UART_RX_FLOW_EN);
|
||||
if (uart_no == UART0)
|
||||
{
|
||||
//set rx fifo trigger
|
||||
WRITE_PERI_REG(UART_CONF1(uart_no),
|
||||
((0x10 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
|
||||
((0x10 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |
|
||||
UART_RX_FLOW_EN |
|
||||
(0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |
|
||||
UART_RX_TOUT_EN);
|
||||
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));
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart1_tx_one_char
|
||||
* Description : Internal used function
|
||||
* Use uart1 interface to transfer one char
|
||||
* Parameters : uint8 TxChar - character to tx
|
||||
* Returns : OK
|
||||
*******************************************************************************/
|
||||
LOCAL 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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart1_write_char
|
||||
* Description : Internal used function
|
||||
* Do some special deal while tx char is '\r' or '\n'
|
||||
* Parameters : char c - character to tx
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart1_write_char(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
uart_tx_one_char(UART1, '\r');
|
||||
uart_tx_one_char(UART1, '\n');
|
||||
}
|
||||
else if (c == '\r')
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
uart_tx_one_char(UART1, c);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart0_write_char(char c)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
uart_tx_one_char(UART0, '\r');
|
||||
uart_tx_one_char(UART0, '\n');
|
||||
}
|
||||
else if (c == '\r')
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
uart_tx_one_char(UART0, c);
|
||||
}
|
||||
}
|
||||
/******************************************************************************
|
||||
* 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++);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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
|
||||
*******************************************************************************/
|
||||
//extern void at_recvTask(void);
|
||||
|
||||
LOCAL void
|
||||
uart0_rx_intr_handler(void *para)
|
||||
{
|
||||
/* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
|
||||
* uart1 and uart0 respectively
|
||||
*/
|
||||
// RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
|
||||
uint8 RcvChar;
|
||||
uint8 uart_no = UART0;//UartDev.buff_uart_no;
|
||||
|
||||
// if (UART_RXFIFO_FULL_INT_ST != (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
|
||||
// {
|
||||
//// at_recvTask();
|
||||
// RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
|
||||
// system_os_post(at_recvTaskPrio, NULL, RcvChar);
|
||||
// WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
|
||||
// }
|
||||
if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST))
|
||||
{
|
||||
os_printf("FRM_ERR\r\n");
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
|
||||
}
|
||||
|
||||
if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST))
|
||||
{
|
||||
// os_printf("fifo full\r\n");
|
||||
ETS_UART_INTR_DISABLE();/////////
|
||||
|
||||
//system_os_post(at_recvTaskPrio, 0, 0);
|
||||
|
||||
// WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
|
||||
// while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
|
||||
// {
|
||||
//// at_recvTask();
|
||||
// RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
|
||||
// system_os_post(at_recvTaskPrio, NULL, RcvChar);
|
||||
// }
|
||||
}
|
||||
else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST))
|
||||
{
|
||||
ETS_UART_INTR_DISABLE();/////////
|
||||
|
||||
//system_os_post(at_recvTaskPrio, 0, 0);
|
||||
|
||||
// WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_TOUT_INT_CLR);
|
||||
//// os_printf("rx time over\r\n");
|
||||
// while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
|
||||
// {
|
||||
//// os_printf("process recv\r\n");
|
||||
//// at_recvTask();
|
||||
// RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
|
||||
// system_os_post(at_recvTaskPrio, NULL, RcvChar);
|
||||
// }
|
||||
}
|
||||
|
||||
// WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
|
||||
|
||||
// if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S))
|
||||
// {
|
||||
// RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xFF;
|
||||
// at_recvTask();
|
||||
// *(pRxBuff->pWritePos) = RcvChar;
|
||||
|
||||
// system_os_post(at_recvTaskPrio, NULL, RcvChar);
|
||||
|
||||
// //insert here for get one command line from uart
|
||||
// if (RcvChar == '\r')
|
||||
// {
|
||||
// pRxBuff->BuffState = WRITE_OVER;
|
||||
// }
|
||||
//
|
||||
// pRxBuff->pWritePos++;
|
||||
//
|
||||
// if (pRxBuff->pWritePos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE))
|
||||
// {
|
||||
// // overflow ...we may need more error handle here.
|
||||
// pRxBuff->pWritePos = pRxBuff->pRcvMsgBuff ;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* 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)
|
||||
{
|
||||
// rom use 74880 baut_rate, here reinitialize
|
||||
UartDev.baut_rate = uart0_br;
|
||||
uart_config(UART0);
|
||||
UartDev.baut_rate = uart1_br;
|
||||
uart_config(UART1);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
||||
// install uart1 putc callback
|
||||
os_install_putc1((void *)uart0_write_char);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart_reattach()
|
||||
{
|
||||
uart_init(BIT_RATE_74880, BIT_RATE_74880);
|
||||
// ETS_UART_INTR_ATTACH(uart_rx_intr_handler_ssc, &(UartDev.rcv_buff));
|
||||
// ETS_UART_INTR_ENABLE();
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef UART_APP_H
|
||||
#define UART_APP_H
|
||||
|
||||
#include "uart_register.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "c_types.h"
|
||||
|
||||
#define RX_BUFF_SIZE 256
|
||||
#define TX_BUFF_SIZE 100
|
||||
#define UART0 0
|
||||
#define UART1 1
|
||||
|
||||
typedef enum {
|
||||
FIVE_BITS = 0x0,
|
||||
SIX_BITS = 0x1,
|
||||
SEVEN_BITS = 0x2,
|
||||
EIGHT_BITS = 0x3
|
||||
} UartBitsNum4Char;
|
||||
|
||||
typedef enum {
|
||||
ONE_STOP_BIT = 0,
|
||||
ONE_HALF_STOP_BIT = BIT2,
|
||||
TWO_STOP_BIT = BIT2
|
||||
} UartStopBitsNum;
|
||||
|
||||
typedef enum {
|
||||
NONE_BITS = 0,
|
||||
ODD_BITS = 0,
|
||||
EVEN_BITS = BIT4
|
||||
} UartParityMode;
|
||||
|
||||
typedef enum {
|
||||
STICK_PARITY_DIS = 0,
|
||||
STICK_PARITY_EN = BIT3 | BIT5
|
||||
} UartExistParity;
|
||||
|
||||
typedef enum {
|
||||
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_256000 = 256000,
|
||||
BIT_RATE_460800 = 460800,
|
||||
BIT_RATE_921600 = 921600
|
||||
} UartBautRate;
|
||||
|
||||
typedef enum {
|
||||
NONE_CTRL,
|
||||
HARDWARE_CTRL,
|
||||
XON_XOFF_CTRL
|
||||
} UartFlowCtrl;
|
||||
|
||||
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; // chip size in byte
|
||||
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);
|
||||
#endif
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
//Generated at 2012-07-03 18:44:06
|
||||
/*
|
||||
* Copyright (c) 2010 - 2011 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UART_REGISTER_H_INCLUDED
|
||||
#define UART_REGISTER_H_INCLUDED
|
||||
#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_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 (BIT(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
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _USER_CONFIG_H_
|
||||
#define _USER_CONFIG_H_
|
||||
#include "user_interface.h"
|
||||
|
||||
#define CFG_HOLDER 0x00FF55A2
|
||||
#define CFG_LOCATION 0x3C
|
||||
|
||||
/*DEFAULT CONFIGURATIONS*/
|
||||
|
||||
#define MQTT_HOST "mqtt.yourserver.com" //or "192.168.11.1"
|
||||
#define MQTT_PORT 8443
|
||||
#define MQTT_BUF_SIZE 1024
|
||||
#define MQTT_KEEPALIVE 120 /*second*/
|
||||
|
||||
#define MQTT_CLIENT_ID "DVES_%08X"
|
||||
#define MQTT_USER "DVES_USER"
|
||||
#define MQTT_PASS "DVES_PASS"
|
||||
|
||||
#define STA_SSID "DVES_HOME"
|
||||
#define STA_PASS "dvespassword"
|
||||
#define STA_TYPE AUTH_WPA2_PSK
|
||||
|
||||
#define MQTT_RECONNECT_TIMEOUT 5 /*second*/
|
||||
#define MQTT_CONNTECT_TIMER 5 /**/
|
||||
|
||||
#define CLIENT_SSL_ENABLE
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
#############################################################
|
||||
# Required variables for each makefile
|
||||
# Discard this section from all parent makefiles
|
||||
# Expected variables (with automatic defaults):
|
||||
# CSRCS (all "C" files in the dir)
|
||||
# SUBDIRS (all subdirs with a Makefile)
|
||||
# GEN_LIBS - list of libs to be generated ()
|
||||
# GEN_IMAGES - list of images to be generated ()
|
||||
# COMPONENTS_xxx - a list of libs/objs in the form
|
||||
# subdir/lib to be extracted and rolled up into
|
||||
# a generated lib/image xxx.a ()
|
||||
#
|
||||
ifndef PDIR
|
||||
GEN_LIBS = libuser.a
|
||||
endif
|
||||
|
||||
|
||||
#############################################################
|
||||
# Configuration i.e. compile options etc.
|
||||
# Target specific stuff (defines etc.) goes in here!
|
||||
# Generally values applying to a tree are captured in the
|
||||
# makefile at its root level - these are then overridden
|
||||
# for a subtree within the makefile rooted therein
|
||||
#
|
||||
#DEFINES +=
|
||||
|
||||
#############################################################
|
||||
# Recursion Magic - Don't touch this!!
|
||||
#
|
||||
# Each subtree potentially has an include directory
|
||||
# corresponding to the common APIs applicable to modules
|
||||
# rooted at that subtree. Accordingly, the INCLUDE PATH
|
||||
# of a module can only contain the include directories up
|
||||
# its parent path, and not its siblings
|
||||
#
|
||||
# Required for each makefile to inherit from the parent
|
||||
#
|
||||
|
||||
INCLUDES := $(INCLUDES) -I $(PDIR)include
|
||||
INCLUDES += -I ./
|
||||
INCLUDES += -I ../../rom/include
|
||||
INCLUDES += -I ../../include/ets
|
||||
PDIR := ../$(PDIR)
|
||||
sinclude $(PDIR)Makefile
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* config.c
|
||||
*
|
||||
* Created on: Dec 6, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
#include "ets_sys.h"
|
||||
#include "os_type.h"
|
||||
#include "mem.h"
|
||||
#include "osapi.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "user_config.h"
|
||||
#include "debug.h"
|
||||
|
||||
SYSCFG sysCfg;
|
||||
SAVE_FLAG saveFlag;
|
||||
|
||||
void CFG_Save()
|
||||
{
|
||||
spi_flash_read((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&saveFlag, sizeof(SAVE_FLAG));
|
||||
|
||||
if (saveFlag.flag == 0) {
|
||||
spi_flash_erase_sector(CFG_LOCATION + 1);
|
||||
spi_flash_write((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&sysCfg, sizeof(SYSCFG));
|
||||
saveFlag.flag = 1;
|
||||
spi_flash_erase_sector(CFG_LOCATION + 3);
|
||||
spi_flash_write((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&saveFlag, sizeof(SAVE_FLAG));
|
||||
} else {
|
||||
spi_flash_erase_sector(CFG_LOCATION + 0);
|
||||
spi_flash_write((CFG_LOCATION + 0) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&sysCfg, sizeof(SYSCFG));
|
||||
saveFlag.flag = 0;
|
||||
spi_flash_erase_sector(CFG_LOCATION + 3);
|
||||
spi_flash_write((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&saveFlag, sizeof(SAVE_FLAG));
|
||||
}
|
||||
}
|
||||
|
||||
void CFG_Load()
|
||||
{
|
||||
|
||||
INFO("\r\nload ...\r\n");
|
||||
spi_flash_read((CFG_LOCATION + 3) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&saveFlag, sizeof(SAVE_FLAG));
|
||||
if (saveFlag.flag == 0) {
|
||||
spi_flash_read((CFG_LOCATION + 0) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&sysCfg, sizeof(SYSCFG));
|
||||
} else {
|
||||
spi_flash_read((CFG_LOCATION + 1) * SPI_FLASH_SEC_SIZE,
|
||||
(uint32 *)&sysCfg, sizeof(SYSCFG));
|
||||
}
|
||||
if(sysCfg.cfg_holder != CFG_HOLDER){
|
||||
os_memset(&sysCfg, 0x00, sizeof sysCfg);
|
||||
|
||||
|
||||
sysCfg.cfg_holder = CFG_HOLDER;
|
||||
|
||||
os_sprintf(sysCfg.sta_ssid, "%s", STA_SSID);
|
||||
os_sprintf(sysCfg.sta_pwd, "%s", STA_PASS);
|
||||
sysCfg.sta_type = STA_TYPE;
|
||||
|
||||
os_sprintf(sysCfg.device_id, MQTT_CLIENT_ID, system_get_chip_id());
|
||||
os_sprintf(sysCfg.mqtt_host, "%s", MQTT_HOST);
|
||||
sysCfg.mqtt_port = MQTT_PORT;
|
||||
os_sprintf(sysCfg.mqtt_user, "%s", MQTT_USER);
|
||||
os_sprintf(sysCfg.mqtt_pass, "%s", MQTT_PASS);
|
||||
|
||||
sysCfg.mqtt_keepalive = MQTT_KEEPALIVE;
|
||||
|
||||
INFO(" default configurations\r\n");
|
||||
|
||||
CFG_Save();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* config.h
|
||||
*
|
||||
* Created on: Dec 6, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
|
||||
#ifndef USER_CONFIG_H_
|
||||
#define USER_CONFIG_H_
|
||||
#include "os_type.h"
|
||||
#include "user_config.h"
|
||||
typedef struct{
|
||||
uint32_t cfg_holder;
|
||||
uint8_t device_id[16];
|
||||
|
||||
uint8_t sta_ssid[32];
|
||||
uint8_t sta_pwd[32];
|
||||
uint32_t sta_type;
|
||||
|
||||
uint8_t mqtt_host[64];
|
||||
uint32_t mqtt_port;
|
||||
uint8_t mqtt_user[32];
|
||||
uint8_t mqtt_pass[32];
|
||||
uint32_t mqtt_keepalive;
|
||||
} SYSCFG;
|
||||
|
||||
typedef struct {
|
||||
uint8 flag;
|
||||
uint8 pad[3];
|
||||
} SAVE_FLAG;
|
||||
|
||||
void CFG_Save();
|
||||
void CFG_Load();
|
||||
|
||||
extern SYSCFG sysCfg;
|
||||
|
||||
#endif /* USER_CONFIG_H_ */
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* debug.h
|
||||
*
|
||||
* Created on: Dec 4, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
|
||||
#ifndef USER_DEBUG_H_
|
||||
#define USER_DEBUG_H_
|
||||
|
||||
|
||||
|
||||
#define INFO os_printf
|
||||
|
||||
#endif /* USER_DEBUG_H_ */
|
|
@ -0,0 +1,533 @@
|
|||
#include "user_interface.h"
|
||||
#include "osapi.h"
|
||||
#include "espconn.h"
|
||||
#include "os_type.h"
|
||||
#include "mem.h"
|
||||
#include "mqtt_msg.h"
|
||||
#include "debug.h"
|
||||
#include "user_config.h"
|
||||
#include "config.h"
|
||||
#include "driver/uart.h"
|
||||
#include "str_queue.h"
|
||||
#include "mqtt.h"
|
||||
|
||||
|
||||
#define MQTT_TASK_PRIO 0
|
||||
#define MQTT_TASK_QUEUE_SIZE 1
|
||||
|
||||
#define MAX_TOPIC_QUEUE 5
|
||||
#define MAX_TOPIC_LEN 64
|
||||
|
||||
#define MAX_PUBLISH_QUEUE 5
|
||||
#define MAX_PUBLISH_LEN 1024
|
||||
|
||||
|
||||
|
||||
unsigned char *default_certificate;
|
||||
unsigned int default_certificate_len = 0;
|
||||
unsigned char *default_private_key;
|
||||
unsigned int default_private_key_len = 0;
|
||||
|
||||
os_event_t mqtt_procTaskQueue[MQTT_TASK_QUEUE_SIZE];
|
||||
|
||||
|
||||
LOCAL void ICACHE_FLASH_ATTR
|
||||
mqtt_dns_found(const char *name, ip_addr_t *ipaddr, void *arg)
|
||||
{
|
||||
struct espconn *pConn = (struct espconn *)arg;
|
||||
MQTT_Client* client = (MQTT_Client *)pConn->reverse;
|
||||
|
||||
|
||||
if(ipaddr == NULL)
|
||||
{
|
||||
INFO("DNS: Found, but got no ip, try to reconnect\r\n");
|
||||
client->connState = TCP_RECONNECT_REQ;
|
||||
return;
|
||||
}
|
||||
|
||||
INFO("DNS: found ip %d.%d.%d.%d\n",
|
||||
*((uint8 *) &ipaddr->addr),
|
||||
*((uint8 *) &ipaddr->addr + 1),
|
||||
*((uint8 *) &ipaddr->addr + 2),
|
||||
*((uint8 *) &ipaddr->addr + 3));
|
||||
|
||||
if(client->ip.addr == 0 && ipaddr->addr != 0)
|
||||
{
|
||||
os_memcpy(client->pCon->proto.tcp->remote_ip, &ipaddr->addr, 4);
|
||||
if(client->security){
|
||||
espconn_secure_connect(client->pCon);
|
||||
}
|
||||
else {
|
||||
espconn_connect(client->pCon);
|
||||
}
|
||||
|
||||
client->connState = TCP_CONNECTING;
|
||||
INFO("TCP: connecting...\r\n");
|
||||
}
|
||||
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
LOCAL void ICACHE_FLASH_ATTR
|
||||
deliver_publish(MQTT_Client* client, uint8_t* message, int length)
|
||||
{
|
||||
|
||||
mqtt_event_data_t event_data;
|
||||
|
||||
event_data.topic_length = length;
|
||||
event_data.topic = mqtt_get_publish_topic(message, &event_data.topic_length);
|
||||
|
||||
event_data.data_length = length;
|
||||
event_data.data = mqtt_get_publish_data(message, &event_data.data_length);
|
||||
|
||||
if(client->dataCb)
|
||||
client->dataCb((uint32_t*)client, event_data.topic, event_data.topic_length, event_data.data, event_data.data_length);
|
||||
|
||||
}
|
||||
|
||||
LOCAL void ICACHE_FLASH_ATTR
|
||||
deliver_publish_continuation(MQTT_Client* client, uint16_t offset, uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
mqtt_event_data_t event_data;
|
||||
|
||||
event_data.type = MQTT_EVENT_TYPE_PUBLISH_CONTINUATION;
|
||||
event_data.topic_length = 0;
|
||||
event_data.topic = NULL;
|
||||
event_data.data_length = length;
|
||||
event_data.data_offset = offset;
|
||||
event_data.data = (char*)buffer;
|
||||
((char*)event_data.data)[event_data.data_length] = '\0';
|
||||
|
||||
//process_post_synch(state->calling_process, mqtt_event, &event_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Client received callback function.
|
||||
* @param arg: contain the ip link information
|
||||
* @param pdata: received data
|
||||
* @param len: the lenght of received data
|
||||
* @retval None
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
mqtt_tcpclient_recv(void *arg, char *pdata, unsigned short len)
|
||||
{
|
||||
uint8_t msg_type;
|
||||
uint8_t msg_qos;
|
||||
|
||||
uint16_t msg_id;
|
||||
|
||||
struct espconn *pCon = (struct espconn*)arg;
|
||||
MQTT_Client *client = (MQTT_Client *)pCon->reverse;
|
||||
|
||||
INFO("TCP: data received\r\n");
|
||||
if(len < MQTT_BUF_SIZE && len > 0){
|
||||
memcpy(client->mqtt_state.in_buffer, pdata, len);
|
||||
|
||||
switch(client->connState){
|
||||
case MQTT_CONNECT_SENDING:
|
||||
if(mqtt_get_type(client->mqtt_state.in_buffer) != MQTT_MSG_TYPE_CONNACK){
|
||||
INFO("MQTT: Invalid packet\r\n");
|
||||
if(client->security){
|
||||
espconn_secure_disconnect(client->pCon);
|
||||
}
|
||||
else {
|
||||
espconn_disconnect(client->pCon);
|
||||
}
|
||||
|
||||
} else {
|
||||
INFO("MQTT: Connected to %s:%d\r\n", client->host, client->port);
|
||||
client->connState = MQTT_SUBSCIBE_SEND;
|
||||
}
|
||||
break;
|
||||
case MQTT_SUBSCIBE_SENDING:
|
||||
if(mqtt_get_type(client->mqtt_state.in_buffer) != MQTT_MSG_TYPE_SUBACK){
|
||||
INFO("MQTT: Invalid packet\r\n");
|
||||
if(client->security){
|
||||
espconn_secure_disconnect(client->pCon);
|
||||
}
|
||||
else{
|
||||
espconn_disconnect(client->pCon);
|
||||
}
|
||||
} else {
|
||||
if(QUEUE_IsEmpty(&client->topicQueue)){
|
||||
client->connState = MQTT_DATA;
|
||||
} else {
|
||||
client->connState = MQTT_SUBSCIBE_SEND;
|
||||
}
|
||||
INFO("MQTT: Subscribe successful\r\n");
|
||||
|
||||
}
|
||||
break;
|
||||
case MQTT_DATA:
|
||||
client->mqtt_state.message_length_read = len;
|
||||
client->mqtt_state.message_length = mqtt_get_total_length(client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);
|
||||
msg_type = mqtt_get_type(client->mqtt_state.in_buffer);
|
||||
msg_qos = mqtt_get_qos(client->mqtt_state.in_buffer);
|
||||
msg_id = mqtt_get_id(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_length);
|
||||
switch(msg_type)
|
||||
{
|
||||
case MQTT_MSG_TYPE_SUBACK:
|
||||
if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_SUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
|
||||
INFO("MQTT: Subscribe successful to %s:%d\r\n", client->host, client->port);
|
||||
break;
|
||||
case MQTT_MSG_TYPE_UNSUBACK:
|
||||
if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_UNSUBSCRIBE && client->mqtt_state.pending_msg_id == msg_id)
|
||||
INFO("MQTT: UnSubscribe successful\r\n");
|
||||
break;
|
||||
case MQTT_MSG_TYPE_PUBLISH:
|
||||
if(msg_qos == 1)
|
||||
client->mqtt_state.outbound_message = mqtt_msg_puback(&client->mqtt_state.mqtt_connection, msg_id);
|
||||
else if(msg_qos == 2)
|
||||
client->mqtt_state.outbound_message = mqtt_msg_pubrec(&client->mqtt_state.mqtt_connection, msg_id);
|
||||
|
||||
deliver_publish(client, client->mqtt_state.in_buffer, client->mqtt_state.message_length_read);
|
||||
break;
|
||||
case MQTT_MSG_TYPE_PUBACK:
|
||||
if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){
|
||||
INFO("MQTT: Publish successful\r\n");
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case MQTT_MSG_TYPE_PUBREC:
|
||||
client->mqtt_state.outbound_message = mqtt_msg_pubrel(&client->mqtt_state.mqtt_connection, msg_id);
|
||||
break;
|
||||
case MQTT_MSG_TYPE_PUBREL:
|
||||
client->mqtt_state.outbound_message = mqtt_msg_pubcomp(&client->mqtt_state.mqtt_connection, msg_id);
|
||||
break;
|
||||
case MQTT_MSG_TYPE_PUBCOMP:
|
||||
if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == msg_id){
|
||||
INFO("MQTT: Public successful\r\n");
|
||||
|
||||
}
|
||||
break;
|
||||
case MQTT_MSG_TYPE_PINGREQ:
|
||||
client->mqtt_state.outbound_message = mqtt_msg_pingresp(&client->mqtt_state.mqtt_connection);
|
||||
break;
|
||||
case MQTT_MSG_TYPE_PINGRESP:
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
// NOTE: this is done down here and not in the switch case above
|
||||
// because the PSOCK_READBUF_LEN() won't work inside a switch
|
||||
// statement due to the way protothreads resume.
|
||||
if(msg_type == MQTT_MSG_TYPE_PUBLISH)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
// adjust message_length and message_length_read so that
|
||||
// they only account for the publish data and not the rest of the
|
||||
// message, this is done so that the offset passed with the
|
||||
// continuation event is the offset within the publish data and
|
||||
// not the offset within the message as a whole.
|
||||
len = client->mqtt_state.message_length_read;
|
||||
mqtt_get_publish_data(client->mqtt_state.in_buffer, &len);
|
||||
len = client->mqtt_state.message_length_read - len;
|
||||
client->mqtt_state.message_length -= len;
|
||||
client->mqtt_state.message_length_read -= len;
|
||||
|
||||
if(client->mqtt_state.message_length_read < client->mqtt_state.message_length)
|
||||
{
|
||||
msg_type = MQTT_PUBLISH_RECV;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case MQTT_PUBLISH_RECV:
|
||||
/*
|
||||
* Long publish message, not implement yet
|
||||
* TODO: Implement method used deliver_publish_continuation
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Client send over callback function.
|
||||
* @param arg: contain the ip link information
|
||||
* @retval None
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
mqtt_tcpclient_sent_cb(void *arg)
|
||||
{
|
||||
struct espconn *pCon = (struct espconn *)arg;
|
||||
MQTT_Client* client = (MQTT_Client *)pCon->reverse;
|
||||
INFO("TCP: Sent\r\n");
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR mqtt_timer(void *arg)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)arg;
|
||||
if(client->connState == MQTT_DATA){
|
||||
client->keepAliveTick ++;
|
||||
if(client->keepAliveTick > client->mqtt_state.connect_info->keepalive){
|
||||
|
||||
INFO("\r\nMQTT: Send keepalive packet to %s:%d!\r\n", client->host, client->port);
|
||||
client->mqtt_state.outbound_message = mqtt_msg_pingreq(&client->mqtt_state.mqtt_connection);
|
||||
client->keepAliveTick = 0;
|
||||
|
||||
}
|
||||
|
||||
} else if(client->connState == TCP_RECONNECT_REQ){
|
||||
client->reconnectTick ++;
|
||||
if(client->reconnectTick > MQTT_RECONNECT_TIMEOUT) {
|
||||
client->reconnectTick = 0;
|
||||
client->connState = TCP_RECONNECT;
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
mqtt_tcpclient_discon_cb(void *arg)
|
||||
{
|
||||
|
||||
struct espconn *pespconn = (struct espconn *)arg;
|
||||
MQTT_Client* client = (MQTT_Client *)pespconn->reverse;
|
||||
INFO("TCP: Disconnected callback\r\n");
|
||||
client->connState = TCP_RECONNECT_REQ;
|
||||
if(client->disconnectedCb)
|
||||
client->disconnectedCb((uint32_t*)client);
|
||||
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Tcp client connect success callback function.
|
||||
* @param arg: contain the ip link information
|
||||
* @retval None
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
mqtt_tcpclient_connect_cb(void *arg)
|
||||
{
|
||||
struct espconn *pCon = (struct espconn *)arg;
|
||||
MQTT_Client* client = (MQTT_Client *)pCon->reverse;
|
||||
|
||||
espconn_regist_disconcb(client->pCon, mqtt_tcpclient_discon_cb);
|
||||
espconn_regist_recvcb(client->pCon, mqtt_tcpclient_recv);////////
|
||||
espconn_regist_sentcb(client->pCon, mqtt_tcpclient_sent_cb);///////
|
||||
INFO("MQTT: Connected to broker %s:%d\r\n", client->host, client->port);
|
||||
client->connState = MQTT_CONNECT_SEND;
|
||||
if(client->connectedCb)
|
||||
client->connectedCb((uint32_t*)client);
|
||||
|
||||
|
||||
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tcp client connect repeat callback function.
|
||||
* @param arg: contain the ip link information
|
||||
* @retval None
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
mqtt_tcpclient_recon_cb(void *arg, sint8 errType)
|
||||
{
|
||||
struct espconn *pCon = (struct espconn *)arg;
|
||||
MQTT_Client* client = (MQTT_Client *)pCon->reverse;
|
||||
|
||||
INFO("TCP: Reconnect to %s:%d\r\n", client->host, client->port);
|
||||
|
||||
client->connState = TCP_RECONNECT_REQ;
|
||||
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain)
|
||||
{
|
||||
|
||||
INFO("MQTT: sending publish...\r\n");
|
||||
client->mqtt_state.outbound_message = mqtt_msg_publish(&client->mqtt_state.mqtt_connection,
|
||||
topic, data, data_length,
|
||||
qos, retain,
|
||||
&client->mqtt_state.pending_msg_id);
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
MQTT_Subscribe(MQTT_Client *client, char* topic)
|
||||
{
|
||||
INFO("MQTT: subscribe, topic\"%s\" at broker %s:%d\r\n", topic, client->host, client->port);
|
||||
|
||||
if(QUEUE_Puts(&client->topicQueue, topic) == -1){
|
||||
INFO("MQTT: Exceed the amount of queues\r\n");
|
||||
} else {
|
||||
if(client->connState == MQTT_DATA)
|
||||
client->connState = MQTT_SUBSCIBE_SEND;
|
||||
}
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)client);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
MQTT_Task(os_event_t *e)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)e->par;
|
||||
uint8_t topic[64];
|
||||
|
||||
switch(client->connState){
|
||||
|
||||
case TCP_RECONNECT_REQ:
|
||||
break;
|
||||
case TCP_RECONNECT:
|
||||
MQTT_Connect(client);
|
||||
INFO("TCP:Reconect to: %s:%d\r\n", client->host, client->port);
|
||||
client->connState = TCP_CONNECTING;
|
||||
break;
|
||||
case MQTT_CONNECT_SEND:
|
||||
|
||||
mqtt_msg_init(&client->mqtt_state.mqtt_connection, client->mqtt_state.out_buffer, client->mqtt_state.out_buffer_length);
|
||||
client->mqtt_state.outbound_message = mqtt_msg_connect(&client->mqtt_state.mqtt_connection, client->mqtt_state.connect_info);
|
||||
if(client->security){
|
||||
espconn_secure_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
espconn_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length);
|
||||
}
|
||||
|
||||
INFO("MQTT: Send mqtt connection info, to broker %s:%d\r\n", client->host, client->port);
|
||||
client->connState = MQTT_CONNECT_SENDING;
|
||||
client->mqtt_state.outbound_message = NULL;
|
||||
break;
|
||||
case MQTT_SUBSCIBE_SEND:
|
||||
if(QUEUE_Gets(&client->topicQueue, topic) == 0){
|
||||
client->mqtt_state.outbound_message = mqtt_msg_subscribe(&client->mqtt_state.mqtt_connection,
|
||||
topic, 0,
|
||||
&client->mqtt_state.pending_msg_id);
|
||||
client->mqtt_state.pending_msg_type = MQTT_MSG_TYPE_SUBSCRIBE;
|
||||
if(client->security){
|
||||
espconn_secure_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length);
|
||||
}
|
||||
else{
|
||||
espconn_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length);
|
||||
}
|
||||
|
||||
client->mqtt_state.outbound_message = NULL;
|
||||
client->connState = MQTT_SUBSCIBE_SENDING;
|
||||
} else {
|
||||
client->connState = MQTT_DATA;
|
||||
}
|
||||
|
||||
break;
|
||||
case MQTT_DATA:
|
||||
if(client->mqtt_state.outbound_message != NULL){
|
||||
if(client->security){
|
||||
espconn_secure_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length);
|
||||
}
|
||||
else{
|
||||
espconn_sent(client->pCon, client->mqtt_state.outbound_message->data, client->mqtt_state.outbound_message->length);
|
||||
}
|
||||
|
||||
client->mqtt_state.outbound_message = NULL;
|
||||
if(client->mqtt_state.pending_msg_type == MQTT_MSG_TYPE_PUBLISH && client->mqtt_state.pending_msg_id == 0)
|
||||
INFO("MQTT: Publish message is done!\r\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32 port, uint8_t security)
|
||||
{
|
||||
INFO("MQTT_InitConnection\r\n");
|
||||
os_memset(mqttClient, 0, sizeof(MQTT_Client));
|
||||
|
||||
mqttClient->pCon = (struct espconn *)os_zalloc(sizeof(struct espconn));
|
||||
mqttClient->pCon->type = ESPCONN_TCP;
|
||||
mqttClient->pCon->state = ESPCONN_NONE;
|
||||
mqttClient->pCon->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
|
||||
mqttClient->pCon->proto.tcp->local_port = espconn_port();
|
||||
mqttClient->pCon->proto.tcp->remote_port = port;
|
||||
mqttClient->host = host;
|
||||
mqttClient->port = port;
|
||||
mqttClient->security = security;
|
||||
mqttClient->pCon->reverse = mqttClient;
|
||||
|
||||
|
||||
espconn_regist_connectcb(mqttClient->pCon, mqtt_tcpclient_connect_cb);
|
||||
espconn_regist_reconcb(mqttClient->pCon, mqtt_tcpclient_recon_cb);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint32_t keepAliveTime)
|
||||
{
|
||||
INFO("MQTT_InitClient\r\n");
|
||||
|
||||
os_memset(&mqttClient->connect_info, 0, sizeof(mqtt_connect_info_t));
|
||||
mqttClient->connect_info.client_id = client_id;
|
||||
mqttClient->connect_info.username = client_user;
|
||||
mqttClient->connect_info.password = client_pass;
|
||||
|
||||
mqttClient->connect_info.keepalive = keepAliveTime;
|
||||
mqttClient->connect_info.clean_session = 1;
|
||||
//mqttClient->mqtt_state = (mqtt_state_t *)os_zalloc(sizeof(mqtt_state_t));
|
||||
|
||||
|
||||
|
||||
mqttClient->mqtt_state.in_buffer = (uint8_t *)os_zalloc(MQTT_BUF_SIZE);
|
||||
mqttClient->mqtt_state.in_buffer_length = MQTT_BUF_SIZE;
|
||||
mqttClient->mqtt_state.out_buffer = (uint8_t *)os_zalloc(MQTT_BUF_SIZE);
|
||||
mqttClient->mqtt_state.out_buffer_length = MQTT_BUF_SIZE;
|
||||
mqttClient->mqtt_state.connect_info = &mqttClient->connect_info;
|
||||
mqttClient->keepAliveTick = 0;
|
||||
mqttClient->reconnectTick = 0;
|
||||
|
||||
os_timer_disarm(&mqttClient->mqttTimer);
|
||||
os_timer_setfn(&mqttClient->mqttTimer, (os_timer_func_t *)mqtt_timer, mqttClient);
|
||||
os_timer_arm(&mqttClient->mqttTimer, 1000, 1);
|
||||
|
||||
QUEUE_Init(&mqttClient->topicQueue, MAX_TOPIC_LEN, MAX_TOPIC_QUEUE);
|
||||
|
||||
system_os_task(MQTT_Task, MQTT_TASK_PRIO, mqtt_procTaskQueue, MQTT_TASK_QUEUE_SIZE);
|
||||
system_os_post(MQTT_TASK_PRIO, 0, (os_param_t)mqttClient);
|
||||
|
||||
}
|
||||
|
||||
void MQTT_Connect(MQTT_Client *mqttClient)
|
||||
{
|
||||
if(UTILS_StrToIP(mqttClient->host, &mqttClient->pCon->proto.tcp->remote_ip)) {
|
||||
INFO("TCP: Connect to ip %s:%d\r\n", mqttClient->host, mqttClient->port);
|
||||
if(mqttClient->security){
|
||||
espconn_secure_connect(mqttClient->pCon);
|
||||
}
|
||||
else {
|
||||
espconn_connect(mqttClient->pCon);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
INFO("TCP: Connect to domain %s:%d\r\n", mqttClient->host, mqttClient->port);
|
||||
espconn_gethostbyname(mqttClient->pCon, mqttClient->host, &mqttClient->ip, mqtt_dns_found);
|
||||
}
|
||||
|
||||
|
||||
mqttClient->connState = TCP_CONNECTING;
|
||||
}
|
||||
void MQTT_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb)
|
||||
{
|
||||
mqttClient->connectedCb = connectedCb;
|
||||
}
|
||||
void MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb)
|
||||
{
|
||||
mqttClient->disconnectedCb = disconnectedCb;
|
||||
}
|
||||
void MQTT_OnData(MQTT_Client *mqttClient, MqttDataCallback dataCb)
|
||||
{
|
||||
mqttClient->dataCb = dataCb;
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* at_mqtt.h
|
||||
*
|
||||
* Created on: Nov 28, 2014
|
||||
* Author: Minh Tuan
|
||||
*/
|
||||
|
||||
#ifndef USER_AT_MQTT_H_
|
||||
#define USER_AT_MQTT_H_
|
||||
#include "mqtt_msg.h"
|
||||
#include "str_queue.h"
|
||||
typedef struct mqtt_event_data_t
|
||||
{
|
||||
uint8_t type;
|
||||
const char* topic;
|
||||
const char* data;
|
||||
uint16_t topic_length;
|
||||
uint16_t data_length;
|
||||
uint16_t data_offset;
|
||||
} mqtt_event_data_t;
|
||||
|
||||
typedef struct mqtt_state_t
|
||||
{
|
||||
uint16_t port;
|
||||
int auto_reconnect;
|
||||
mqtt_connect_info_t* connect_info;
|
||||
uint8_t* in_buffer;
|
||||
uint8_t* out_buffer;
|
||||
int in_buffer_length;
|
||||
int out_buffer_length;
|
||||
uint16_t message_length;
|
||||
uint16_t message_length_read;
|
||||
mqtt_message_t* outbound_message;
|
||||
mqtt_connection_t mqtt_connection;
|
||||
uint16_t pending_msg_id;
|
||||
int pending_msg_type;
|
||||
} mqtt_state_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_INIT,
|
||||
WIFI_CONNECTING,
|
||||
WIFI_CONNECTING_ERROR,
|
||||
WIFI_CONNECTED,
|
||||
DNS_RESOLVE,
|
||||
TCP_DISCONNECTED,
|
||||
TCP_RECONNECT_REQ,
|
||||
TCP_RECONNECT,
|
||||
TCP_CONNECTING,
|
||||
TCP_CONNECTING_ERROR,
|
||||
TCP_CONNECTED,
|
||||
MQTT_CONNECT_SEND,
|
||||
MQTT_CONNECT_SENDING,
|
||||
MQTT_SUBSCIBE_SEND,
|
||||
MQTT_SUBSCIBE_SENDING,
|
||||
MQTT_DATA,
|
||||
MQTT_PUBLISH_RECV,
|
||||
MQTT_PUBLISHING
|
||||
} tConnState;
|
||||
|
||||
typedef void (*MqttCallback)(uint32_t *args);
|
||||
typedef void (*MqttDataCallback)(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh);
|
||||
|
||||
typedef struct {
|
||||
struct espconn *pCon;
|
||||
uint8_t security;
|
||||
uint8_t* host;
|
||||
uint32_t port;
|
||||
ip_addr_t ip;
|
||||
mqtt_state_t mqtt_state;
|
||||
mqtt_connect_info_t connect_info;
|
||||
MqttCallback connectedCb;
|
||||
MqttCallback disconnectedCb;
|
||||
MqttDataCallback dataCb;
|
||||
ETSTimer mqttTimer;
|
||||
uint32_t keepAliveTick;
|
||||
uint32_t reconnectTick;
|
||||
tConnState connState;
|
||||
STR_QUEUE topicQueue;
|
||||
} MQTT_Client;
|
||||
|
||||
#define SEC_NONSSL 0
|
||||
#define SEC_SSL 1
|
||||
|
||||
#define MQTT_FLAG_CONNECTED 1
|
||||
#define MQTT_FLAG_READY 2
|
||||
#define MQTT_FLAG_EXIT 4
|
||||
|
||||
#define MQTT_EVENT_TYPE_NONE 0
|
||||
#define MQTT_EVENT_TYPE_CONNECTED 1
|
||||
#define MQTT_EVENT_TYPE_DISCONNECTED 2
|
||||
#define MQTT_EVENT_TYPE_SUBSCRIBED 3
|
||||
#define MQTT_EVENT_TYPE_UNSUBSCRIBED 4
|
||||
#define MQTT_EVENT_TYPE_PUBLISH 5
|
||||
#define MQTT_EVENT_TYPE_PUBLISHED 6
|
||||
#define MQTT_EVENT_TYPE_EXITED 7
|
||||
#define MQTT_EVENT_TYPE_PUBLISH_CONTINUATION 8
|
||||
|
||||
void MQTT_InitConnection(MQTT_Client *mqttClient, uint8_t* host, uint32 port, uint8_t security);
|
||||
void MQTT_InitClient(MQTT_Client *mqttClient, uint8_t* client_id, uint8_t* client_user, uint8_t* client_pass, uint32_t keepAliveTime);
|
||||
void MQTT_OnConnected(MQTT_Client *mqttClient, MqttCallback connectedCb);
|
||||
void MQTT_OnDisconnected(MQTT_Client *mqttClient, MqttCallback disconnectedCb);
|
||||
void MQTT_OnData(MQTT_Client *mqttClient, MqttDataCallback dataCb);
|
||||
void MQTT_Subscribe(MQTT_Client *client, char* topic);
|
||||
void MQTT_Connect(MQTT_Client *mqttClient);
|
||||
void MQTT_Publish(MQTT_Client *client, const char* topic, const char* data, int data_length, int qos, int retain);
|
||||
|
||||
#endif /* USER_AT_MQTT_H_ */
|
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "mqtt_msg.h"
|
||||
|
||||
#define MQTT_MAX_FIXED_HEADER_SIZE 3
|
||||
|
||||
enum mqtt_connect_flag
|
||||
{
|
||||
MQTT_CONNECT_FLAG_USERNAME = 1 << 7,
|
||||
MQTT_CONNECT_FLAG_PASSWORD = 1 << 6,
|
||||
MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5,
|
||||
MQTT_CONNECT_FLAG_WILL = 1 << 2,
|
||||
MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1
|
||||
};
|
||||
|
||||
struct __attribute((__packed__)) mqtt_connect_variable_header
|
||||
{
|
||||
uint8_t lengthMsb;
|
||||
uint8_t lengthLsb;
|
||||
uint8_t magic[6];
|
||||
uint8_t version;
|
||||
uint8_t flags;
|
||||
uint8_t keepaliveMsb;
|
||||
uint8_t keepaliveLsb;
|
||||
};
|
||||
|
||||
static int append_string(mqtt_connection_t* connection, const char* string, int len)
|
||||
{
|
||||
if(connection->message.length + len + 2 > connection->buffer_length)
|
||||
return -1;
|
||||
|
||||
connection->buffer[connection->message.length++] = len >> 8;
|
||||
connection->buffer[connection->message.length++] = len & 0xff;
|
||||
memcpy(connection->buffer + connection->message.length, string, len);
|
||||
connection->message.length += len;
|
||||
|
||||
return len + 2;
|
||||
}
|
||||
|
||||
static uint16_t append_message_id(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
// If message_id is zero then we should assign one, otherwise
|
||||
// we'll use the one supplied by the caller
|
||||
while(message_id == 0)
|
||||
message_id = ++connection->message_id;
|
||||
|
||||
if(connection->message.length + 2 > connection->buffer_length)
|
||||
return 0;
|
||||
|
||||
connection->buffer[connection->message.length++] = message_id >> 8;
|
||||
connection->buffer[connection->message.length++] = message_id & 0xff;
|
||||
|
||||
return message_id;
|
||||
}
|
||||
|
||||
static int init_message(mqtt_connection_t* connection)
|
||||
{
|
||||
connection->message.length = MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
return MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
}
|
||||
|
||||
static mqtt_message_t* fail_message(mqtt_connection_t* connection)
|
||||
{
|
||||
connection->message.data = connection->buffer;
|
||||
connection->message.length = 0;
|
||||
return &connection->message;
|
||||
}
|
||||
|
||||
static mqtt_message_t* fini_message(mqtt_connection_t* connection, int type, int dup, int qos, int retain)
|
||||
{
|
||||
int remaining_length = connection->message.length - MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
|
||||
if(remaining_length > 127)
|
||||
{
|
||||
connection->buffer[0] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
connection->buffer[1] = 0x80 | (remaining_length % 128);
|
||||
connection->buffer[2] = remaining_length / 128;
|
||||
connection->message.length = remaining_length + 3;
|
||||
connection->message.data = connection->buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
connection->buffer[1] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
connection->buffer[2] = remaining_length;
|
||||
connection->message.length = remaining_length + 2;
|
||||
connection->message.data = connection->buffer + 1;
|
||||
}
|
||||
|
||||
return &connection->message;
|
||||
}
|
||||
|
||||
void mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length)
|
||||
{
|
||||
memset(connection, 0, sizeof(connection));
|
||||
connection->buffer = buffer;
|
||||
connection->buffer_length = buffer_length;
|
||||
}
|
||||
|
||||
int mqtt_get_total_length(uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
|
||||
for(i = 1; i < length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
return totlen;
|
||||
}
|
||||
|
||||
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
int topiclen;
|
||||
|
||||
for(i = 1; i < *length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i -1));
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
if(i + 2 >= *length)
|
||||
return NULL;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if(i + topiclen >= *length)
|
||||
return NULL;
|
||||
|
||||
*length = topiclen;
|
||||
return (const char*)(buffer + i);
|
||||
}
|
||||
|
||||
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length)
|
||||
{
|
||||
int i;
|
||||
int totlen = 0;
|
||||
int topiclen;
|
||||
|
||||
for(i = 1; i < *length; ++i)
|
||||
{
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
totlen += i;
|
||||
|
||||
if(i + 2 >= *length)
|
||||
return NULL;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if(i + topiclen >= *length)
|
||||
return NULL;
|
||||
i += topiclen;
|
||||
|
||||
if(mqtt_get_qos(buffer) > 0)
|
||||
{
|
||||
if(i + 2 >= *length)
|
||||
return NULL;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if(totlen < i)
|
||||
return NULL;
|
||||
|
||||
if(totlen <= *length)
|
||||
*length = totlen - i;
|
||||
else
|
||||
*length = *length - i;
|
||||
return (const char*)(buffer + i);
|
||||
}
|
||||
|
||||
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
if(length < 1)
|
||||
return 0;
|
||||
|
||||
switch(mqtt_get_type(buffer))
|
||||
{
|
||||
case MQTT_MSG_TYPE_PUBLISH:
|
||||
{
|
||||
int i;
|
||||
int topiclen;
|
||||
|
||||
for(i = 1; i < length; ++i)
|
||||
{
|
||||
if((buffer[i] & 0x80) == 0)
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i + 2 >= length)
|
||||
return 0;
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if(i + topiclen >= length)
|
||||
return 0;
|
||||
i += topiclen;
|
||||
|
||||
if(mqtt_get_qos(buffer) > 0)
|
||||
{
|
||||
if(i + 2 >= length)
|
||||
return 0;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
return (buffer[i] << 8) | buffer[i + 1];
|
||||
}
|
||||
case MQTT_MSG_TYPE_PUBACK:
|
||||
case MQTT_MSG_TYPE_PUBREC:
|
||||
case MQTT_MSG_TYPE_PUBREL:
|
||||
case MQTT_MSG_TYPE_PUBCOMP:
|
||||
case MQTT_MSG_TYPE_SUBACK:
|
||||
case MQTT_MSG_TYPE_UNSUBACK:
|
||||
{
|
||||
// This requires the remaining length to be encoded in 1 byte,
|
||||
// which it should be.
|
||||
if(length >= 4 && (buffer[1] & 0x80) == 0)
|
||||
return (buffer[2] << 8) | buffer[3];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info)
|
||||
{
|
||||
struct mqtt_connect_variable_header* variable_header;
|
||||
|
||||
init_message(connection);
|
||||
|
||||
if(connection->message.length + sizeof(*variable_header) > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
variable_header = (void*)(connection->buffer + connection->message.length);
|
||||
connection->message.length += sizeof(*variable_header);
|
||||
|
||||
variable_header->lengthMsb = 0;
|
||||
variable_header->lengthLsb = 6;
|
||||
memcpy(variable_header->magic, "MQIsdp", 6);
|
||||
variable_header->version = 3;
|
||||
variable_header->flags = 0;
|
||||
variable_header->keepaliveMsb = info->keepalive >> 8;
|
||||
variable_header->keepaliveLsb = info->keepalive & 0xff;
|
||||
|
||||
if(info->clean_session)
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
|
||||
|
||||
if(info->client_id != NULL && info->client_id[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->client_id, strlen(info->client_id)) < 0)
|
||||
return fail_message(connection);
|
||||
}
|
||||
else
|
||||
return fail_message(connection);
|
||||
|
||||
if(info->will_topic != NULL && info->will_topic[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->will_topic, strlen(info->will_topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, info->will_message, strlen(info->will_message)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_WILL;
|
||||
if(info->will_retain)
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
|
||||
variable_header->flags |= (info->will_qos & 3) << 4;
|
||||
}
|
||||
|
||||
if(info->username != NULL && info->username[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->username, strlen(info->username)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_USERNAME;
|
||||
}
|
||||
|
||||
if(info->password != NULL && info->password[0] != '\0')
|
||||
{
|
||||
if(append_string(connection, info->password, strlen(info->password)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
variable_header->flags |= MQTT_CONNECT_FLAG_PASSWORD;
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_CONNECT, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if(topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(qos > 0)
|
||||
{
|
||||
if((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
}
|
||||
else
|
||||
*message_id = 0;
|
||||
|
||||
if(connection->message.length + data_length > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
memcpy(connection->buffer + connection->message.length, data, data_length);
|
||||
connection->message.length += data_length;
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBACK, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREC, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREL, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
if(append_message_id(connection, message_id) == 0)
|
||||
return fail_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if(topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(connection->message.length + 1 > connection->buffer_length)
|
||||
return fail_message(connection);
|
||||
connection->buffer[connection->message.length++] = qos;
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_SUBSCRIBE, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id)
|
||||
{
|
||||
init_message(connection);
|
||||
|
||||
if(topic == NULL || topic[0] == '\0')
|
||||
return fail_message(connection);
|
||||
|
||||
if((*message_id = append_message_id(connection, 0)) == 0)
|
||||
return fail_message(connection);
|
||||
|
||||
if(append_string(connection, topic, strlen(topic)) < 0)
|
||||
return fail_message(connection);
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_SUBSCRIBE, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pingreq(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_pingresp(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PINGRESP, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t* mqtt_msg_disconnect(mqtt_connection_t* connection)
|
||||
{
|
||||
init_message(connection);
|
||||
return fini_message(connection, MQTT_MSG_TYPE_DISCONNECT, 0, 0, 0);
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* File: mqtt_msg.h
|
||||
* Author: Minh Tuan
|
||||
*
|
||||
* Created on July 12, 2014, 1:05 PM
|
||||
*/
|
||||
|
||||
#ifndef MQTT_MSG_H
|
||||
#define MQTT_MSG_H
|
||||
#include "c_types.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/* 7 6 5 4 3 2 1 0*/
|
||||
/*| --- Message Type---- | DUP Flag | QoS Level | Retain |
|
||||
/* Remaining Length */
|
||||
|
||||
|
||||
enum mqtt_message_type
|
||||
{
|
||||
MQTT_MSG_TYPE_CONNECT = 1,
|
||||
MQTT_MSG_TYPE_CONNACK = 2,
|
||||
MQTT_MSG_TYPE_PUBLISH = 3,
|
||||
MQTT_MSG_TYPE_PUBACK = 4,
|
||||
MQTT_MSG_TYPE_PUBREC = 5,
|
||||
MQTT_MSG_TYPE_PUBREL = 6,
|
||||
MQTT_MSG_TYPE_PUBCOMP = 7,
|
||||
MQTT_MSG_TYPE_SUBSCRIBE = 8,
|
||||
MQTT_MSG_TYPE_SUBACK = 9,
|
||||
MQTT_MSG_TYPE_UNSUBSCRIBE = 10,
|
||||
MQTT_MSG_TYPE_UNSUBACK = 11,
|
||||
MQTT_MSG_TYPE_PINGREQ = 12,
|
||||
MQTT_MSG_TYPE_PINGRESP = 13,
|
||||
MQTT_MSG_TYPE_DISCONNECT = 14
|
||||
};
|
||||
|
||||
typedef struct mqtt_message
|
||||
{
|
||||
uint8_t* data;
|
||||
uint16_t length;
|
||||
|
||||
} mqtt_message_t;
|
||||
|
||||
typedef struct mqtt_connection
|
||||
{
|
||||
mqtt_message_t message;
|
||||
|
||||
uint16_t message_id;
|
||||
uint8_t* buffer;
|
||||
uint16_t buffer_length;
|
||||
|
||||
} mqtt_connection_t;
|
||||
|
||||
typedef struct mqtt_connect_info
|
||||
{
|
||||
const char* client_id;
|
||||
const char* username;
|
||||
const char* password;
|
||||
const char* will_topic;
|
||||
const char* will_message;
|
||||
int keepalive;
|
||||
int will_qos;
|
||||
int will_retain;
|
||||
int clean_session;
|
||||
|
||||
} mqtt_connect_info_t;
|
||||
|
||||
|
||||
static inline int mqtt_get_type(uint8_t* buffer) { return (buffer[0] & 0xf0) >> 4; }
|
||||
static inline int mqtt_get_dup(uint8_t* buffer) { return (buffer[0] & 0x08) >> 3; }
|
||||
static inline int mqtt_get_qos(uint8_t* buffer) { return (buffer[0] & 0x06) >> 1; }
|
||||
static inline int mqtt_get_retain(uint8_t* buffer) { return (buffer[0] & 0x01); }
|
||||
|
||||
void mqtt_msg_init(mqtt_connection_t* connection, uint8_t* buffer, uint16_t buffer_length);
|
||||
int mqtt_get_total_length(uint8_t* buffer, uint16_t length);
|
||||
const char* mqtt_get_publish_topic(uint8_t* buffer, uint16_t* length);
|
||||
const char* mqtt_get_publish_data(uint8_t* buffer, uint16_t* length);
|
||||
uint16_t mqtt_get_id(uint8_t* buffer, uint16_t length);
|
||||
|
||||
mqtt_message_t* mqtt_msg_connect(mqtt_connection_t* connection, mqtt_connect_info_t* info);
|
||||
mqtt_message_t* mqtt_msg_publish(mqtt_connection_t* connection, const char* topic, const char* data, int data_length, int qos, int retain, uint16_t* message_id);
|
||||
mqtt_message_t* mqtt_msg_puback(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_pubrec(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_pubrel(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_pubcomp(mqtt_connection_t* connection, uint16_t message_id);
|
||||
mqtt_message_t* mqtt_msg_subscribe(mqtt_connection_t* connection, const char* topic, int qos, uint16_t* message_id);
|
||||
mqtt_message_t* mqtt_msg_unsubscribe(mqtt_connection_t* connection, const char* topic, uint16_t* message_id);
|
||||
mqtt_message_t* mqtt_msg_pingreq(mqtt_connection_t* connection);
|
||||
mqtt_message_t* mqtt_msg_pingresp(mqtt_connection_t* connection);
|
||||
mqtt_message_t* mqtt_msg_disconnect(mqtt_connection_t* connection);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MQTT_MSG_H */
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* str_queue.c
|
||||
*
|
||||
* Created on: Dec 30, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
#include "str_queue.h"
|
||||
#include "user_interface.h"
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
#include "mem.h"
|
||||
|
||||
void QUEUE_Init(STR_QUEUE *queue, int strLen, int maxString)
|
||||
{
|
||||
queue->buf = (uint8_t*)os_zalloc(strLen*maxString);
|
||||
queue->size = maxString;
|
||||
queue->strLen = strLen;
|
||||
queue->pr = queue->pw = 0;
|
||||
}
|
||||
int32_t QUEUE_Puts(STR_QUEUE *queue, char* str)
|
||||
{
|
||||
uint32_t next = (queue->pw + 1)%queue->size;
|
||||
if(next == queue->pr) return -1;
|
||||
os_strcpy(queue->buf + queue->pw*queue->strLen, str);
|
||||
queue->pw = next;
|
||||
return 0;
|
||||
}
|
||||
int32_t QUEUE_Gets(STR_QUEUE *queue, char* str)
|
||||
{
|
||||
if(queue->pr == queue->pw) return -1;
|
||||
os_strcpy(str, queue->buf + queue->pr*queue->strLen);
|
||||
queue->pr = (queue->pr + 1) % queue->size;
|
||||
return 0;
|
||||
}
|
||||
int32_t QUEUE_IsEmpty(STR_QUEUE *queue)
|
||||
{
|
||||
return (queue->pr == queue->pw);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* str_queue.h
|
||||
*
|
||||
* Created on: Dec 30, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
|
||||
#ifndef USER_STR_QUEUE_H_
|
||||
#define USER_STR_QUEUE_H_
|
||||
#include "os_type.h"
|
||||
typedef struct {
|
||||
uint8_t *buf;
|
||||
uint32_t pr;
|
||||
uint32_t pw;
|
||||
uint32_t size;
|
||||
uint32_t strLen;
|
||||
} STR_QUEUE;
|
||||
|
||||
void QUEUE_Init(STR_QUEUE *queue, int strLen, int strSize);
|
||||
int32_t QUEUE_Puts(STR_QUEUE *queue, char* str);
|
||||
int32_t QUEUE_Gets(STR_QUEUE *queue, char* str);
|
||||
int32_t QUEUE_IsEmpty(STR_QUEUE *queue);
|
||||
#endif /* USER_STR_QUEUE_H_ */
|
|
@ -0,0 +1,57 @@
|
|||
#include "ets_sys.h"
|
||||
#include "driver/uart.h"
|
||||
#include "osapi.h"
|
||||
#include "mqtt.h"
|
||||
#include "wifi.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "gpio.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
MQTT_Client mqttClient;
|
||||
|
||||
void wifiConnectCb(uint8_t status)
|
||||
{
|
||||
if(status == STATION_GOT_IP){
|
||||
MQTT_Connect(&mqttClient);
|
||||
|
||||
MQTT_Subscribe(&mqttClient, "/test/topic");
|
||||
MQTT_Subscribe(&mqttClient, "/test2/topic");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
void mqttConnectedCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
INFO("MQTT: Connected\r\n");
|
||||
}
|
||||
|
||||
void mqttDisconnectedCb(uint32_t *args)
|
||||
{
|
||||
MQTT_Client* client = (MQTT_Client*)args;
|
||||
INFO("MQTT: Disconnected\r\n");
|
||||
}
|
||||
void mqttDataCb(uint32_t *args, const char* topic, uint32_t topic_len, const char *data, uint32_t lengh)
|
||||
{
|
||||
INFO("MQTT topic: %s, data: %s \r\n", topic, data);
|
||||
}
|
||||
|
||||
|
||||
void user_init(void)
|
||||
{
|
||||
uart_init(BIT_RATE_115200, BIT_RATE_115200);
|
||||
os_delay_us(1000000);
|
||||
|
||||
CFG_Load();
|
||||
|
||||
MQTT_InitConnection(&mqttClient, sysCfg.mqtt_host, sysCfg.mqtt_port, SEC_SSL);
|
||||
MQTT_InitClient(&mqttClient, sysCfg.device_id, sysCfg.mqtt_user, sysCfg.mqtt_pass, sysCfg.mqtt_keepalive);
|
||||
MQTT_OnConnected(&mqttClient, mqttConnectedCb);
|
||||
MQTT_OnDisconnected(&mqttClient, mqttDisconnectedCb);
|
||||
MQTT_OnData(&mqttClient, mqttDataCb);
|
||||
|
||||
WIFI_Connect(sysCfg.sta_ssid, sysCfg.sta_pwd, wifiConnectCb);
|
||||
|
||||
INFO("\r\nSystem started ...\r\n");
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Tuan PM
|
||||
* Email: tuanpm@live.com
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
uint8_t UTILS_IsIPV4 (int8_t *str)
|
||||
{
|
||||
uint8_t segs = 0; /* Segment count. */
|
||||
uint8_t chcnt = 0; /* Character count within segment. */
|
||||
uint8_t accum = 0; /* Accumulator for segment. */
|
||||
/* Catch NULL pointer. */
|
||||
if (str == 0)
|
||||
return 0;
|
||||
/* Process every character in string. */
|
||||
|
||||
while (*str != '\0') {
|
||||
/* Segment changeover. */
|
||||
|
||||
if (*str == '.') {
|
||||
/* Must have some digits in segment. */
|
||||
if (chcnt == 0)
|
||||
return 0;
|
||||
/* Limit number of segments. */
|
||||
if (++segs == 4)
|
||||
return 0;
|
||||
/* Reset segment values and restart loop. */
|
||||
chcnt = accum = 0;
|
||||
str++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check numeric. */
|
||||
if ((*str < '0') || (*str > '9'))
|
||||
return 0;
|
||||
|
||||
/* Accumulate and check segment. */
|
||||
|
||||
if ((accum = accum * 10 + *str - '0') > 255)
|
||||
return 0;
|
||||
/* Advance other segment specific stuff and continue loop. */
|
||||
|
||||
chcnt++;
|
||||
str++;
|
||||
}
|
||||
|
||||
/* Check enough segments and enough characters in last segment. */
|
||||
|
||||
if (segs != 3)
|
||||
return 0;
|
||||
if (chcnt == 0)
|
||||
return 0;
|
||||
/* Address okay. */
|
||||
|
||||
return 1;
|
||||
}
|
||||
uint8_t UTILS_StrToIP(const int8_t* str, void *ip)
|
||||
{
|
||||
|
||||
/* The count of the number of bytes processed. */
|
||||
int i;
|
||||
/* A pointer to the next digit to process. */
|
||||
const char * start;
|
||||
|
||||
start = str;
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* The digit being processed. */
|
||||
char c;
|
||||
/* The value of this byte. */
|
||||
int n = 0;
|
||||
while (1) {
|
||||
c = * start;
|
||||
start++;
|
||||
if (c >= '0' && c <= '9') {
|
||||
n *= 10;
|
||||
n += c - '0';
|
||||
}
|
||||
/* We insist on stopping at "." if we are still parsing
|
||||
the first, second, or third numbers. If we have reached
|
||||
the end of the numbers, we will allow any character. */
|
||||
else if ((i < 3 && c == '.') || i == 3) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (n >= 256) {
|
||||
return 0;
|
||||
}
|
||||
((uint8_t*)ip)[i] = n;
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
uint32_t UTILS_Atoh(const int8_t *s)
|
||||
{
|
||||
uint32_t value = 0, digit;
|
||||
int8_t c;
|
||||
|
||||
while((c = *s++)){
|
||||
if('0' <= c && c <= '9')
|
||||
digit = c - '0';
|
||||
else if('A' <= c && c <= 'F')
|
||||
digit = c - 'A' + 10;
|
||||
else if('a' <= c && c<= 'f')
|
||||
digit = c - 'a' + 10;
|
||||
else break;
|
||||
|
||||
value = (value << 4) | digit;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _UTILS_H_
|
||||
#define _UTILS_H_
|
||||
|
||||
#include "c_types.h"
|
||||
|
||||
uint32_t UTILS_Atoh(const int8_t *s);
|
||||
uint8_t UTILS_StrToIP(const int8_t* str, void *ip);
|
||||
uint8_t UTILS_IsIPV4 (int8_t *str);
|
||||
char *ULTILS_StrReplace(char *orig, char *rep, char *with);
|
||||
#endif
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* wifi.c
|
||||
*
|
||||
* Created on: Dec 30, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
#include "wifi.h"
|
||||
#include "user_interface.h"
|
||||
#include "osapi.h"
|
||||
#include "espconn.h"
|
||||
#include "os_type.h"
|
||||
#include "mem.h"
|
||||
#include "mqtt_msg.h"
|
||||
#include "debug.h"
|
||||
#include "user_config.h"
|
||||
#include "config.h"
|
||||
#include "driver/uart.h"
|
||||
|
||||
static ETSTimer WiFiLinker;
|
||||
WifiCallback wifiCb = NULL;
|
||||
static uint8_t wifiStatus = STATION_IDLE, lastWifiStatus = STATION_IDLE;
|
||||
static void ICACHE_FLASH_ATTR wifi_check_ip(void *arg)
|
||||
{
|
||||
struct ip_info ipConfig;
|
||||
|
||||
os_timer_disarm(&WiFiLinker);
|
||||
wifi_get_ip_info(STATION_IF, &ipConfig);
|
||||
wifiStatus = wifi_station_get_connect_status();
|
||||
if (wifiStatus == STATION_GOT_IP && ipConfig.ip.addr != 0)
|
||||
{
|
||||
|
||||
os_timer_setfn(&WiFiLinker, (os_timer_func_t *)wifi_check_ip, NULL);
|
||||
os_timer_arm(&WiFiLinker, 2000, 0);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(wifi_station_get_connect_status() == STATION_WRONG_PASSWORD)
|
||||
{
|
||||
|
||||
INFO("STATION_WRONG_PASSWORD\r\n");
|
||||
wifi_station_connect();
|
||||
|
||||
|
||||
}
|
||||
else if(wifi_station_get_connect_status() == STATION_NO_AP_FOUND)
|
||||
{
|
||||
|
||||
INFO("STATION_NO_AP_FOUND\r\n");
|
||||
wifi_station_connect();
|
||||
|
||||
|
||||
}
|
||||
else if(wifi_station_get_connect_status() == STATION_CONNECT_FAIL)
|
||||
{
|
||||
|
||||
INFO("STATION_CONNECT_FAIL\r\n");
|
||||
wifi_station_connect();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO("STATION_IDLE\r\n");
|
||||
}
|
||||
|
||||
os_timer_setfn(&WiFiLinker, (os_timer_func_t *)wifi_check_ip, NULL);
|
||||
os_timer_arm(&WiFiLinker, 500, 0);
|
||||
}
|
||||
if(wifiStatus != lastWifiStatus){
|
||||
lastWifiStatus = wifiStatus;
|
||||
if(wifiCb)
|
||||
wifiCb(wifiStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void WIFI_Connect(uint8_t* ssid, uint8_t* pass, WifiCallback cb)
|
||||
{
|
||||
struct station_config stationConf;
|
||||
|
||||
INFO("WIFI_INIT\r\n");
|
||||
wifi_set_opmode(STATION_MODE);
|
||||
wifi_station_set_auto_connect(FALSE);
|
||||
wifiCb = cb;
|
||||
|
||||
os_memset(&stationConf, 0, sizeof(struct station_config));
|
||||
|
||||
os_sprintf(stationConf.ssid, "%s", ssid);
|
||||
os_sprintf(stationConf.password, "%s", pass);
|
||||
|
||||
wifi_station_set_config(&stationConf);
|
||||
|
||||
os_timer_disarm(&WiFiLinker);
|
||||
os_timer_setfn(&WiFiLinker, (os_timer_func_t *)wifi_check_ip, NULL);
|
||||
os_timer_arm(&WiFiLinker, 1000, 0);
|
||||
|
||||
wifi_station_set_auto_connect(TRUE);
|
||||
wifi_station_connect();
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* wifi.h
|
||||
*
|
||||
* Created on: Dec 30, 2014
|
||||
* Author: Minh
|
||||
*/
|
||||
|
||||
#ifndef USER_WIFI_H_
|
||||
#define USER_WIFI_H_
|
||||
#include "os_type.h"
|
||||
typedef void (*WifiCallback)(uint8_t);
|
||||
void WIFI_Connect(uint8_t* ssid, uint8_t* pass, WifiCallback cb);
|
||||
|
||||
|
||||
#endif /* USER_WIFI_H_ */
|
Ładowanie…
Reference in New Issue