diff --git a/.astylerc b/.astylerc new file mode 100644 index 0000000..ebd67ec --- /dev/null +++ b/.astylerc @@ -0,0 +1,23 @@ +# Coding standard for MySensors core library (see https://www.mysensors.org/download/contributing) + +# Curly braces should follow "One True Brace Style" format +style=1tbs + +# All control statements ('if', 'for', 'while' etc.) should include curly braces {}. Even one-liners. +add-brackets + +# Tab-character for white space/indentation +indent=tab + +# All lines should be kept at 100 character width or less +max-code-length=100 +break-after-logical + +# Preprocessor blocks should be indented +indent-preproc-block + +# Preprocessor definitions should be indented if linebroken +indent-preproc-define + +# C++ comments should be indented to source level, and not be kept in first column +indent-col1-comments diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..c2b4a9a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,19 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with UTF-8 encoding for every file +[*] +end_of_line = lf +charset = utf-8 + +# For all source code +[*.{c,cpp,h,ino}] +insert_final_newline = true +indent_style = tab +indent_size = 2 + +# Tab indentation also for makefiles +[Makefile] +indent_style = tab diff --git a/.gitattributes b/.gitattributes index 4635737..415abee 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ # Set default behaviour, in case users don't have core.autocrlf set. -* text=auto +* text eol=lf # Explicitly declare text files we want to always be normalized and converted # to native line endings on checkout. diff --git a/.gitignore b/.gitignore index 980b4fc..02d1910 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ stino.settings MyPrivateConfig.h Documentation/html doxygen_sqlite3.db +Makefile.inc +build +bin diff --git a/Makefile b/Makefile index 3ee190c..d307e32 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,10 @@ # # Makefile for MySensors # +# +# The arduino library build part were inspired by +# Arduino-Makefile project, Copyright (C) 2012 Sudar +# # Description: # ------------ # use make all and make install to install the gateway @@ -11,42 +15,92 @@ CONFIG_FILE=Makefile.inc include $(CONFIG_FILE) -GATEWAY_BIN=mysGateway -GATEWAY=examples_linux/$(GATEWAY_BIN) +CPPFLAGS+=-Ofast -g -Wall -Wextra +DEPFLAGS=-MT $@ -MMD -MP + +GATEWAY_BIN=mysgw +GATEWAY=$(BINDIR)/$(GATEWAY_BIN) GATEWAY_C_SOURCES=$(wildcard drivers/Linux/*.c) -GATEWAY_CPP_SOURCES=$(wildcard drivers/Linux/*.cpp) examples_linux/mysGateway.cpp -OBJECTS=$(patsubst %.c,%.o,$(GATEWAY_C_SOURCES)) $(patsubst %.cpp,%.o,$(GATEWAY_CPP_SOURCES)) +GATEWAY_CPP_SOURCES=$(wildcard drivers/Linux/*.cpp) examples_linux/mysgw.cpp +GATEWAY_OBJECTS=$(patsubst %.c,$(BUILDDIR)/%.o,$(GATEWAY_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(GATEWAY_CPP_SOURCES)) -DEPS+=$(patsubst %.c,%.d,$(GATEWAY_C_SOURCES)) $(patsubst %.cpp,%.d,$(GATEWAY_CPP_SOURCES)) - -CINCLUDE=-I. -I./core -I./drivers/Linux +INCLUDES=-I. -I./core -I./drivers/Linux ifeq ($(SOC),$(filter $(SOC),BCM2835 BCM2836)) RPI_C_SOURCES=$(wildcard drivers/RPi/*.c) RPI_CPP_SOURCES=$(wildcard drivers/RPi/*.cpp) -OBJECTS+=$(patsubst %.c,%.o,$(RPI_C_SOURCES)) $(patsubst %.cpp,%.o,$(RPI_CPP_SOURCES)) +GATEWAY_OBJECTS+=$(patsubst %.c,$(BUILDDIR)/%.o,$(RPI_C_SOURCES)) $(patsubst %.cpp,$(BUILDDIR)/%.o,$(RPI_CPP_SOURCES)) -DEPS+=$(patsubst %.c,%.d,$(RPI_C_SOURCES)) $(patsubst %.cpp,%.d,$(RPI_CPP_SOURCES)) - -CINCLUDE+=-I./drivers/RPi +INCLUDES+=-I./drivers/RPi endif -.PHONY: all gateway cleanconfig clean install uninstall force +# Gets include flags for library +get_library_includes = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.properties)), \ + -I$(1)/src, \ + $(addprefix -I,$(1) $(wildcard $(1)/utility))) -all: $(GATEWAY) +# Gets all sources with given extension (param2) for library (path = param1) +# for old (1.0.x) layout looks in . and "utility" directories +# for new (1.5.x) layout looks in src and recursively its subdirectories +get_library_files = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.properties)), \ + $(call rwildcard,$(1)/src/,*.$(2)), \ + $(wildcard $(1)/*.$(2) $(1)/utility/*.$(2))) + +ifdef ARDUINO_LIB_DIR +ARDUINO=arduino +ARDUINO_LIBS:=$(shell find $(ARDUINO_LIB_DIR) -mindepth 1 -maxdepth 1 -type d) +ARDUINO_INCLUDES:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_includes,$(lib))) +ARDUINO_LIB_CPP_SRCS:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_files,$(lib),cpp)) +ARDUINO_LIB_C_SRCS:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_files,$(lib),c)) +ARDUINO_LIB_AS_SRCS:=$(foreach lib, $(ARDUINO_LIBS), $(call get_library_files,$(lib),S)) +ARDUINO_LIB_OBJS=$(patsubst $(ARDUINO_LIB_DIR)/%.cpp,$(BUILDDIR)/arduinolibs/%.cpp.o,$(ARDUINO_LIB_CPP_SRCS)) \ + $(patsubst $(ARDUINO_LIB_DIR)/%.c,$(BUILDDIR)/arduinolibs/%.c.o,$(ARDUINO_LIB_C_SRCS)) \ + $(patsubst $(ARDUINO_LIB_DIR)/%.S,$(BUILDDIR)/arduinolibs/%.S.o,$(ARDUINO_LIB_AS_SRCS)) + +INCLUDES+=$(ARDUINO_INCLUDES) +DEPS+=$(ARDUINO_LIB_OBJS:.o=.d) +endif + +DEPS+=$(GATEWAY_OBJECTS:.o=.d) + +.PHONY: all createdir cleanconfig clean install uninstall + +all: createdir $(ARDUINO) $(GATEWAY) + +createdir: + @mkdir -p $(BUILDDIR) $(BINDIR) + +# Arduino libraries Build +$(ARDUINO): CPPFLAGS+=-DARDUINO=100 +$(ARDUINO): $(ARDUINO_LIB_OBJS) + @printf "[Done building Arduino Libraries]\n" # Gateway Build -$(GATEWAY): $(OBJECTS) - $(CXX) $(LDFLAGS) -o $@ $(OBJECTS) +$(GATEWAY): $(GATEWAY_OBJECTS) $(ARDUINO_LIB_OBJS) + $(CXX) $(LDFLAGS) -o $@ $(GATEWAY_OBJECTS) $(ARDUINO_LIB_OBJS) # Include all .d files -include $(DEPS) -%.o: %.cpp - $(CXX) $(CXXFLAGS) $(CINCLUDE) -MMD -c -o $@ $< +$(BUILDDIR)/arduinolibs/%.cpp.o: $(ARDUINO_LIB_DIR)/%.cpp + @mkdir -p $(dir $@) + $(CXX) $(DEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ -%.o: %.c - $(CC) $(CFLAGS) $(CINCLUDE) -MMD -c -o $@ $< +$(BUILDDIR)/arduinolibs/%.c.o: $(ARDUINO_LIB_DIR)/%.c + @mkdir -p $(dir $@) + $(CC) $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -c $< -o $@ + +$(BUILDDIR)/arduinolibs/%.S.o: $(ARDUINO_LIB_DIR)/%.S + @mkdir -p $(dir $@) + $(CC) $(DEPFLAGS) $(CPPFLAGS) $(ASFLAGS) $(INCLUDES) -c $< -o $@ + +$(BUILDDIR)/%.o: %.cpp + @mkdir -p $(dir $@) + $(CXX) $(DEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ + +$(BUILDDIR)/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -c $< -o $@ # clear configuration files cleanconfig: @@ -56,7 +110,7 @@ cleanconfig: # clear build files clean: @echo "[Cleaning]" - rm -rf build $(OBJECTS) $(GATEWAY) $(DEPS) + rm -rf $(BUILDDIR) $(BINDIR) $(CONFIG_FILE): @echo "[Running configure]" @@ -70,31 +124,31 @@ install-gateway: install-initscripts: ifeq ($(INIT_SYSTEM), systemd) - install -m0644 initscripts/mysgateway.systemd /etc/systemd/system/mysgateway.service - @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" /etc/systemd/system/mysgateway.service + install -m0644 initscripts/mysgw.systemd /etc/systemd/system/mysgw.service + @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" /etc/systemd/system/mysgw.service systemctl daemon-reload @echo "MySensors gateway has been installed, to add to the boot run:" - @echo " sudo systemctl enable mysgateway.service" + @echo " sudo systemctl enable mysgw.service" @echo "To start the gateway run:" - @echo " sudo systemctl start mysgateway.service" + @echo " sudo systemctl start mysgw.service" else ifeq ($(INIT_SYSTEM), sysvinit) - install -m0755 initscripts/mysgateway.sysvinit /etc/init.d/mysgateway - @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" /etc/init.d/mysgateway + install -m0755 initscripts/mysgw.sysvinit /etc/init.d/mysgw + @sed -i -e "s|%gateway_dir%|${GATEWAY_DIR}|g" /etc/init.d/mysgw @echo "MySensors gateway has been installed, to add to the boot run:" - @echo " sudo update-rc.d mysgateway defaults" + @echo " sudo update-rc.d mysgw defaults" @echo "To start the gateway run:" - @echo " sudo service mysgateway start" + @echo " sudo service mysgw start" endif uninstall: ifeq ($(INIT_SYSTEM), systemd) - @echo "Stopping daemon mysgateway (ignore errors)" - -@systemctl stop mysgateway.service + @echo "Stopping daemon mysgw (ignore errors)" + -@systemctl stop mysgw.service @echo "removing files" - rm /etc/systemd/system/mysgateway.service $(GATEWAY_DIR)/$(GATEWAY_BIN) + rm /etc/systemd/system/mysgw.service $(GATEWAY_DIR)/$(GATEWAY_BIN) else ifeq ($(INIT_SYSTEM), sysvinit) - @echo "Stopping daemon mysgateway (ignore errors)" - -@service mysgateway stop + @echo "Stopping daemon mysgw (ignore errors)" + -@service mysgw stop @echo "removing files" - rm /etc/init.d/mysgateway $(GATEWAY_DIR)/$(GATEWAY_BIN) + rm /etc/init.d/mysgw $(GATEWAY_DIR)/$(GATEWAY_BIN) endif diff --git a/MyConfig.h b/MyConfig.h index 4df97a8..2addec2 100644 --- a/MyConfig.h +++ b/MyConfig.h @@ -513,13 +513,6 @@ #else #define MY_RF24_CS_PIN 10 #endif -#endif - /** - * @def MY_RF24_IRQ_PIN - * @brief Default RF24 IRQ pin setting. Override in sketch if needed. - */ -#ifndef MY_RF24_IRQ_PIN -#define MY_RF24_IRQ_PIN RF24_IRQ_PIN #endif /** @@ -956,7 +949,6 @@ #define MY_PARENT_NODE_IS_STATIC #define MY_REGISTRATION_CONTROLLER #define MY_TRANSPORT_UPLINK_CHECK_DISABLED -#define MY_TRANSPORT_RELAXED #define MY_DEBUG_VERBOSE_RF24 #define MY_TRANSPORT_SANITY_CHECK #define MY_RF24_IRQ_PIN diff --git a/MySensors.h b/MySensors.h index 73925e9..b012d19 100644 --- a/MySensors.h +++ b/MySensors.h @@ -79,7 +79,7 @@ #endif // LEDS -#if !defined(MY_DEFAULT_ERR_LED_PIN) & defined(MY_HW_ERR_LED_PIN) +#if !defined(MY_DEFAULT_ERR_LED_PIN) && defined(MY_HW_ERR_LED_PIN) #define MY_DEFAULT_ERR_LED_PIN MY_HW_ERR_LED_PIN #endif @@ -240,7 +240,7 @@ #endif #if defined(MY_TRANSPORT_DONT_CARE_MODE) - #error This directive is deprecated, use MY_TRANSPORT_RELAXED instead! + #error This directive is deprecated, set MY_TRANSPORT_WAIT_READY_MS instead! #endif diff --git a/README.md b/README.md index db75a27..c3d55e4 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,19 @@ Arduino ======= -MySensors Arduino Library v2.0.0-beta +MySensors Arduino Library v2.1.0-beta Please visit www.mysensors.org for more information Doxygen ------- -[master](https://ci.mysensors.org/job/Verifiers/job/MySensorsArduino/branch/master/Doxygen_HTML/index.html) [development](https://ci.mysensors.org/job/Verifiers/job/MySensorsArduino/branch/development/Doxygen_HTML/index.html) +[master](https://ci.mysensors.org/job/Verifiers/job/MySensors/branch/master/Doxygen_HTML/index.html) [development](https://ci.mysensors.org/job/Verifiers/job/MySensors/branch/development/Doxygen_HTML/index.html) CI statuses ----------- -Current build status of master branch: [![Build Status](https://ci.mysensors.org/job/Verifiers/job/MySensorsArduino/job/master/badge/icon)](https://ci.mysensors.org/job/Verifiers/job/MySensorsArduino/job/master/) +Current build status of master branch: [![Build Status](https://ci.mysensors.org/job/Verifiers/job/MySensors/job/master/badge/icon)](https://ci.mysensors.org/job/Verifiers/job/MySensors/job/master/) -Current build status of development branch: [![Build Status](https://ci.mysensors.org/job/Verifiers/job/MySensorsArduino/job/development/badge/icon)](https://ci.mysensors.org/job/Verifiers/job/MySensorsArduino/job/development/) - -Current build status of master branch (nightly build): [![Build Status](https://ci.mysensors.org/job/Nightlies/job/MySensorsArduinoNightly/job/master/badge/icon)](https://ci.mysensors.org/job/Nightlies/job/MySensorsArduinoNightly/job/master/) - -Current build status of development branch (nightly build): [![Build Status](https://ci.mysensors.org/job/Nightlies/job/MySensorsArduinoNightly/job/development/badge/icon)](https://ci.mysensors.org/job/Nightlies/job/MySensorsArduinoNightly/job/development/) +Current build status of development branch: [![Build Status](https://ci.mysensors.org/job/Verifiers/job/MySensors/job/development/badge/icon)](https://ci.mysensors.org/job/Verifiers/job/MySensors/job/development/) Current build status of master branch (nightly build of Arduino IDE): [![Build Status](https://ci.mysensors.org/job/Nightlies/job/MySensorsArduinoNightlyIDE/job/master/badge/icon)](https://ci.mysensors.org/job/Nightlies/job/MySensorsArduinoNightlyIDE/job/master/) diff --git a/configure b/configure index 4d54aa1..f172cf5 100755 --- a/configure +++ b/configure @@ -14,10 +14,15 @@ Help: Building options: --soc=[BCM2835|BCM2836|AM33XX|A10|A13|A20|H3] SoC type to be used. [configure autodetected] - --cpu-flags= CPU defining/optimizing flags to be used. [configure autodetected] - --extra-cxxflags= Extra C flags passed to C/C++ compilation. [] + --cpu-flags= CPU defining/optimizing flags to be used. [configure autodetected] + --extra-cflags= Extra C flags passed to C compilation. [] + --extra-cxxflags= Extra C++ flags passed to C++ compilation. [] --extra-ldflags= Extra C flags passed to linking. [] + --c_compiler= C compiler. [arm-linux-gnueabihf-gcc][gcc] --cxx_compiler= C++ compiler [arm-linux-gnueabihf-g++][g++] + --build-dir= Compiler directory to store object files. [build] + --bin-dir= Compiler directory to store binary files. [bin] + --arduino-lib-dir= Arduino library directory. --no-clean Don't clean previous build artifacts. Installation options: @@ -48,7 +53,7 @@ MySensors options: MQTT publish topic prefix. --my-mqtt-subscribe-topic-prefix= MQTT subscribe topic prefix. - --my-transport=[none|nrf24|rs485] + --my-transport=[none|nrf24|rs485|rfm95] Transport type, set to none to disable transport feature. [nrf24] --my-rf24-channel=<0-125> RF channel for the sensor net, 0-125. [76] --my-rf24-pa-level=[RF24_PA_MAX|RF24_PA_LOW] @@ -175,10 +180,10 @@ function gcc_cpu_flags { local soc=$1 case $soc in BCM2835) - flags="-march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -DLINUX_ARCH_RASPBERRYPI" + flags="-march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard" ;; BCM2836) - flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -DLINUX_ARCH_RASPBERRYPI" + flags="-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard" ;; AM33XX) flags="-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard" @@ -206,7 +211,7 @@ debug=enable gateway_type=ethernet transport_type=nrf24 -params="SOC CXXFLAGS LDFLAGS PREFIX CXX GATEWAY_DIR INIT_SYSTEM" +params="SOC CFLAGS CXXFLAGS CPPFLAGS LDFLAGS PREFIX CC CXX ARDUINO_LIB_DIR BUILDDIR BINDIR GATEWAY_DIR INIT_SYSTEM" for opt do if [ "$opt" = "-h" ] || [ "$opt" = "--help" ]; then @@ -221,15 +226,30 @@ for opt do --cpu-flags=*) CPUFLAGS="$optarg" ;; + --extra-cflags=*) + CFLAGS="$optarg" + ;; --extra-cxxflags=*) CXXFLAGS="$optarg" ;; --extra-ldflags=*) LDFLAGS="$optarg" ;; + --c_compiler=*) + CC="$optarg" + ;; --cxx_compiler=*) CXX="$optarg" ;; + --arduino-lib-dir=*) + ARDUINO_LIB_DIR=$optarg + ;; + --build-dir=*) + BUILDDIR="$optarg" + ;; + --bin-dir=*) + BINDIR="$optarg" + ;; --no-clean*) NO_CLEAN="1" ;; @@ -247,10 +267,10 @@ for opt do ;; --my-node-id=*) gateway_type="none"; - CXXFLAGS="-DMY_NODE_ID=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_NODE_ID=${optarg} $CPPFLAGS" ;; --my-config-file=*) - CXXFLAGS="-DMY_LINUX_CONFIG_FILE=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_LINUX_CONFIG_FILE=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-transport=*) transport_type=${optarg} @@ -260,74 +280,74 @@ for opt do transport_type=${optarg} ;; --my-serial-port=*) - CXXFLAGS="-DMY_LINUX_SERIAL_PORT=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_LINUX_SERIAL_PORT=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-serial-baudrate=*) - CXXFLAGS="-DMY_BAUD_RATE=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_BAUD_RATE=${optarg} $CPPFLAGS" ;; --my-serial-is-pty*) - CXXFLAGS="-DMY_IS_SERIAL_PTY $CXXFLAGS" + CPPFLAGS="-DMY_IS_SERIAL_PTY $CPPFLAGS" ;; --my-serial-pty=*) - CXXFLAGS="-DMY_LINUX_SERIAL_PTY=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_LINUX_SERIAL_PTY=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-serial-groupname=*) - CXXFLAGS="-DMY_LINUX_SERIAL_GROUPNAME=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_LINUX_SERIAL_GROUPNAME=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-rf24-channel=*) - CXXFLAGS="-DMY_RF24_CHANNEL=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_RF24_CHANNEL=${optarg} $CPPFLAGS" ;; --my-rf24-pa-level=*) - CXXFLAGS="-DMY_RF24_PA_LEVEL=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_RF24_PA_LEVEL=${optarg} $CPPFLAGS" ;; --my-controller-url-address=*) - CXXFLAGS="-DMY_CONTROLLER_URL_ADDRESS=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_CONTROLLER_URL_ADDRESS=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-controller-ip-address=*) controller_ip=`echo ${optarg//./,}` - CXXFLAGS="-DMY_CONTROLLER_IP_ADDRESS=${controller_ip} $CXXFLAGS" + CPPFLAGS="-DMY_CONTROLLER_IP_ADDRESS=${controller_ip} $CPPFLAGS" ;; --my-port=*) - CXXFLAGS="-DMY_PORT=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_PORT=${optarg} $CPPFLAGS" ;; --my-mqtt-client-id=*) - CXXFLAGS="-DMY_MQTT_CLIENT_ID=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_MQTT_CLIENT_ID=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-mqtt-publish-topic-prefix=*) - CXXFLAGS="-DMY_MQTT_PUBLISH_TOPIC_PREFIX=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_MQTT_PUBLISH_TOPIC_PREFIX=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-mqtt-subscribe-topic-prefix=*) - CXXFLAGS="-DMY_MQTT_SUBSCRIBE_TOPIC_PREFIX=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_MQTT_SUBSCRIBE_TOPIC_PREFIX=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-rf24-irq-pin=*) - CXXFLAGS="-DMY_RX_MESSAGE_BUFFER_FEATURE -DMY_RF24_IRQ_PIN=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_RX_MESSAGE_BUFFER_FEATURE -DMY_RF24_IRQ_PIN=${optarg} $CPPFLAGS" ;; --my-rx-message-buffer-size=*) - CXXFLAGS="-DMY_RX_MESSAGE_BUFFER_SIZE=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_RX_MESSAGE_BUFFER_SIZE=${optarg} $CPPFLAGS" ;; --my-rs485-serial-port=*) - CXXFLAGS="-DMY_RS485_HWSERIAL=\\\"${optarg}\\\" $CXXFLAGS" + CPPFLAGS="-DMY_RS485_HWSERIAL=\\\"${optarg}\\\" $CPPFLAGS" ;; --my-rs485-baudrate=*) - CXXFLAGS="-DMY_RS485_BAUD_RATE=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_RS485_BAUD_RATE=${optarg} $CPPFLAGS" ;; --my-rs485-de-pin=*) - CXXFLAGS="-DMY_RS485_DE_PIN=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_RS485_DE_PIN=${optarg} $CPPFLAGS" ;; --my-rs485-max-msg-length=*) - CXXFLAGS="-DMY_RS485_MAX_MESSAGE_LENGTH=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_RS485_MAX_MESSAGE_LENGTH=${optarg} $CPPFLAGS" ;; --my-leds-err-pin=*) - CXXFLAGS="-DMY_DEFAULT_ERR_LED_PIN=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_DEFAULT_ERR_LED_PIN=${optarg} $CPPFLAGS" ;; --my-leds-rx-pin=*) - CXXFLAGS="-DMY_DEFAULT_RX_LED_PIN=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_DEFAULT_RX_LED_PIN=${optarg} $CPPFLAGS" ;; --my-leds-tx-pin=*) - CXXFLAGS="-DMY_DEFAULT_TX_LED_PIN=${optarg} $CXXFLAGS" + CPPFLAGS="-DMY_DEFAULT_TX_LED_PIN=${optarg} $CPPFLAGS" ;; --my-leds-blinking-inverse*) - CXXFLAGS="-DMY_WITH_LEDS_BLINKING_INVERSE $CXXFLAGS" + CPPFLAGS="-DMY_WITH_LEDS_BLINKING_INVERSE $CPPFLAGS" ;; *) echo "[WARNING] Unknown option detected:$opt, ignored" @@ -336,7 +356,10 @@ for opt do done PREFIX=${PREFIX:-/usr/local} +BUILDDIR=${BUILDDIR:-build} +BINDIR=${BINDIR:-bin} GATEWAY_DIR=${GATEWAY_DIR:-${PREFIX}/bin} +CC=${CC:-gcc} CXX=${CXX:-g++} if [ -z "${SOC}" ]; then @@ -353,32 +376,43 @@ if [ -z "${CPUFLAGS}" ]; then CPUFLAGS=$(gcc_cpu_flags $SOC) fi -CXXFLAGS="$CPUFLAGS -Ofast -g -Wall -Wextra $CXXFLAGS" -CFLAGS="-Ofast -g -Wall -Wextra $CFLAGS" +if [[ $SOC == "BCM2835" || $SOC == "BCM2836" ]]; then + CPPFLAGS="-DLINUX_ARCH_RASPBERRYPI $CPPFLAGS" +fi if [[ $TYPE == "RPi2" || $TYPE == "RPi3" || $REV == "0010" ]]; then - CXXFLAGS+="-D__RPI_BPLUS" + CPPFLAGS="-D__RPI_BPLUS $CPPFLAGS" fi if [[ ${debug} == "enable" ]]; then - CXXFLAGS="-DMY_DEBUG $CXXFLAGS" + CPPFLAGS="-DMY_DEBUG $CPPFLAGS" fi if [[ ${gateway_type} == "ethernet" ]]; then - CXXFLAGS="-DMY_GATEWAY_LINUX $CXXFLAGS" + CPPFLAGS="-DMY_GATEWAY_LINUX $CPPFLAGS" elif [[ ${gateway_type} == "serial" ]]; then - CXXFLAGS="-DMY_GATEWAY_SERIAL $CXXFLAGS" + CPPFLAGS="-DMY_GATEWAY_SERIAL $CPPFLAGS" elif [[ ${gateway_type} == "mqtt" ]]; then - CXXFLAGS="-DMY_GATEWAY_LINUX -DMY_GATEWAY_MQTT_CLIENT $CXXFLAGS" + CPPFLAGS="-DMY_GATEWAY_LINUX -DMY_GATEWAY_MQTT_CLIENT $CPPFLAGS" fi -if [[ ${transport_type} == "nrf24" ]]; then - CXXFLAGS="-DMY_RADIO_NRF24 $CXXFLAGS" +if [[ ${transport_type} == "none" ]]; then + # Transport disabled + : +elif [[ ${transport_type} == "nrf24" ]]; then + CPPFLAGS="-DMY_RADIO_NRF24 $CPPFLAGS" elif [[ ${transport_type} == "rs485" ]]; then - CXXFLAGS="-DMY_RS485 $CXXFLAGS" + CPPFLAGS="-DMY_RS485 $CPPFLAGS" +elif [[ ${transport_type} == "rfm95" ]]; then + CPPFLAGS="-DMY_RADIO_RFM95 $CPPFLAGS" +else + echo "Invalid transport type." + echo "Aborting." + exit 1 fi LDFLAGS="-pthread $LDFLAGS" +CPPFLAGS="$CPUFLAGS $CPPFLAGS" if [ -x /usr/bin/systemctl ] || [ -x /bin/systemctl ]; then INIT_SYSTEM=systemd diff --git a/core/MyHwATMega328.h b/core/MyHwATMega328.h index bf38a24..bb5962f 100644 --- a/core/MyHwATMega328.h +++ b/core/MyHwATMega328.h @@ -73,15 +73,9 @@ do { \ #define hwMillis() millis() #define hwRandomNumberInit() randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN)) #define hwReadConfig(__pos) eeprom_read_byte((uint8_t*)(__pos)) - -#ifndef eeprom_update_byte - #define hwWriteConfig(__loc, __val) if((uint8_t)(__val) != eeprom_read_byte((uint8_t*)(__loc))) { eeprom_write_byte((uint8_t*)(__loc), (__val)); } -#else - #define hwWriteConfig(__pos, __val) eeprom_update_byte((uint8_t*)(__pos), (__val)) -#endif - +#define hwWriteConfig(__pos, __val) eeprom_update_byte((uint8_t*)(__pos), (__val)) #define hwReadConfigBlock(__buf, __pos, __length) eeprom_read_block((void*)(__buf), (void*)(__pos), (__length)) -#define hwWriteConfigBlock(__buf, __pos, __length) eeprom_write_block((void*)(__buf), (void*)(__pos), (__length)) +#define hwWriteConfigBlock(__buf, __pos, __length) eeprom_update_block((void*)(__buf), (void*)(__pos), (__length)) diff --git a/core/MyHwLinuxGeneric.cpp b/core/MyHwLinuxGeneric.cpp index a71c323..ea7a47c 100644 --- a/core/MyHwLinuxGeneric.cpp +++ b/core/MyHwLinuxGeneric.cpp @@ -5,8 +5,8 @@ * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * - * Created by Marcelo Aquino - * Copyright (C) 2016 Marcelo Aquino + * Created by Henrik Ekblad + * Copyright (C) 2013-2016 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org diff --git a/core/MyHwLinuxGeneric.h b/core/MyHwLinuxGeneric.h index ff8b008..4603176 100644 --- a/core/MyHwLinuxGeneric.h +++ b/core/MyHwLinuxGeneric.h @@ -5,8 +5,8 @@ * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * - * Created by Marcelo Aquino - * Copyright (C) 2016 Marcelo Aquino + * Created by Henrik Ekblad + * Copyright (C) 2013-2016 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org diff --git a/core/MyHwRPi.cpp b/core/MyHwRPi.cpp index 34c530f..79c04ce 100644 --- a/core/MyHwRPi.cpp +++ b/core/MyHwRPi.cpp @@ -5,8 +5,8 @@ * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * - * Created by Marcelo Aquino - * Copyright (C) 2016 Marcelo Aquino + * Created by Henrik Ekblad + * Copyright (C) 2013-2016 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org @@ -22,17 +22,11 @@ #include #include #include "SoftEeprom.h" -#include "log.h" static SoftEeprom eeprom = SoftEeprom(MY_LINUX_CONFIG_FILE, 1024); // ATMega328 has 1024 bytes void hwInit() { - if (!bcm2835_init()) { - logError("Failed to initialized bcm2835.\n"); - exit(1); - } - #ifdef MY_GATEWAY_SERIAL MY_SERIALDEVICE.begin(MY_BAUD_RATE); #ifdef MY_LINUX_SERIAL_GROUPNAME diff --git a/core/MyHwRPi.h b/core/MyHwRPi.h index f6bbb8e..2252a22 100644 --- a/core/MyHwRPi.h +++ b/core/MyHwRPi.h @@ -5,8 +5,8 @@ * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * - * Created by Marcelo Aquino - * Copyright (C) 2016 Marcelo Aquino + * Created by Henrik Ekblad + * Copyright (C) 2013-2016 Sensnology AB * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors * * Documentation: http://www.mysensors.org @@ -20,7 +20,24 @@ #ifndef MyHwRPi_h #define MyHwRPi_h +#include #include "MyHwLinuxGeneric.h" +#include "log.h" +#include "bcm2835.h" + +class Bcm2835Init { +public: + Bcm2835Init() { + if (!bcm2835_init()) { + logError("Failed to initialized bcm2835.\n"); + exit(1); + } + } + ~Bcm2835Init() { + bcm2835_close(); + } +}; +Bcm2835Init bcm2835Init; #undef hwDigitalWrite inline void hwDigitalWrite(uint8_t, uint8_t); diff --git a/core/MyMainLinux.cpp b/core/MyMainLinux.cpp index e6155ba..7c4ec6b 100644 --- a/core/MyMainLinux.cpp +++ b/core/MyMainLinux.cpp @@ -102,7 +102,7 @@ static int daemonize(void) void print_usage() { - printf("Usage: mysGateway [options]\n\n" \ + printf("Usage: mysgw [options]\n\n" \ "Options:\n" \ " -h, --help Display a short summary of all program options.\n" \ " -d, --debug Enable debug.\n" \ @@ -154,7 +154,7 @@ void generate_soft_sign_hmac_key() print_soft_sign_hmac_key(key); - printf("To use this key, run mysGateway with:\n" + printf("To use this key, run mysgw with:\n" " --set-soft-hmac-key="); for (int i = 0; i < 32; i++) { printf("%02X", key[i]); @@ -226,7 +226,7 @@ void generate_soft_sign_serial_key() print_soft_sign_serial_key(key); - printf("To use this key, run mysGateway with:\n" + printf("To use this key, run mysgw with:\n" " --set-soft-serial-key="); for (int i = 0; i < 9; i++) { printf("%02X", key[i]); @@ -298,7 +298,7 @@ void generate_aes_key() print_aes_key(key); - printf("To use this key, run mysGateway with:\n" + printf("To use this key, run mysgw with:\n" " --set-aes-key="); for (int i = 0; i < 16; i++) { printf("%02X", key[i]); diff --git a/core/MyTransport.cpp b/core/MyTransport.cpp index 7c86062..180e939 100644 --- a/core/MyTransport.cpp +++ b/core/MyTransport.cpp @@ -98,13 +98,13 @@ void stInitUpdate(void) { // GW mode: skip FPAR,ID,UPL states transportSwitchSM(stReady); #else - if ((uint8_t)MY_NODE_ID != AUTO) { + #if MY_NODE_ID != AUTO TRANSPORT_DEBUG(PSTR("TSM:INIT:STATID=%d\n"),(uint8_t)MY_NODE_ID); // Set static ID _transportConfig.nodeId = (uint8_t)MY_NODE_ID; // Save static ID to eeprom (for bootloader) hwWriteConfig(EEPROM_NODE_ID_ADDRESS, (uint8_t)MY_NODE_ID); - } + #endif // assign ID if set if (_transportConfig.nodeId == AUTO || transportAssignNodeID(_transportConfig.nodeId)) { // if node ID valid (>0 and <255), proceed to next state diff --git a/core/Version.h b/core/Version.h index b279f56..0f781ab 100644 --- a/core/Version.h +++ b/core/Version.h @@ -24,6 +24,6 @@ #ifndef Version_h #define Version_h -#define MYSENSORS_LIBRARY_VERSION "2.0.1-beta" +#define MYSENSORS_LIBRARY_VERSION "2.1.0-beta" #endif diff --git a/drivers/Linux/Arduino.h b/drivers/Linux/Arduino.h index eaa4ed9..71bca23 100644 --- a/drivers/Linux/Arduino.h +++ b/drivers/Linux/Arduino.h @@ -68,6 +68,7 @@ using std::abs; typedef bool boolean; typedef uint8_t byte; typedef string String; +typedef char __FlashStringHelper; void yield(void); unsigned long millis(void); diff --git a/drivers/RFM95/RFM95.cpp b/drivers/RFM95/RFM95.cpp index 316040e..37bcf51 100644 --- a/drivers/RFM95/RFM95.cpp +++ b/drivers/RFM95/RFM95.cpp @@ -24,6 +24,11 @@ #include "RFM95.h" +#if defined(LINUX_ARCH_RASPBERRYPI) +uint8_t spi_rxbuff[32 + 1]; //SPI receive buffer (payload max 32 bytes, MYS protocol limitation) +uint8_t spi_txbuff[32 + 1]; //SPI transmit buffer (payload max 32 bytes + 1 byte for the command, MYS protocol limitation) +#endif + LOCAL void RFM95_csn(const bool level) { hwDigitalWrite(MY_RFM95_SPI_CS, level); } @@ -31,11 +36,41 @@ LOCAL void RFM95_csn(const bool level) { LOCAL uint8_t RFM95_spiMultiByteTransfer(const uint8_t cmd, uint8_t* buf, uint8_t len, const bool aReadMode) { uint8_t status; uint8_t* current = buf; - noInterrupts(); #if !defined(MY_SOFTSPI) _SPI.beginTransaction(SPISettings(MY_RFM95_SPI_MAX_SPEED, MY_RFM95_SPI_DATA_ORDER, MY_RFM95_SPI_DATA_MODE)); #endif RFM95_csn(LOW); +#if defined(LINUX_ARCH_RASPBERRYPI) + uint8_t * prx = spi_rxbuff; + uint8_t * ptx = spi_txbuff; + uint8_t size = len + 1; // Add register value to transmit buffer + + *ptx++ = cmd; + while (len--) { + if (aReadMode) { + *ptx++ = RF24_NOP; + } + else { + *ptx++ = *current++; + } + } + _SPI.transfernb((char *)spi_txbuff, (char *)spi_rxbuff, size); + if (aReadMode) { + if (size == 2) { + status = *++prx; // result is 2nd byte of receive buffer + } + else { + status = *prx++; // status is 1st byte of receive buffer + // decrement before to skip status byte + while (--size) { + *buf++ = *prx++; + } + } + } + else { + status = *prx; // status is 1st byte of receive buffer + } +#else status = _SPI.transfer(cmd); while (len--) { if (aReadMode) { @@ -46,11 +81,11 @@ LOCAL uint8_t RFM95_spiMultiByteTransfer(const uint8_t cmd, uint8_t* buf, uint8_ } else status = _SPI.transfer(*current++); } +#endif RFM95_csn(HIGH); #if !defined(MY_SOFTSPI) _SPI.endTransaction(); #endif - interrupts(); return status; } @@ -114,9 +149,9 @@ LOCAL bool RFM95_initialise(const float frequency) { RFM95_writeReg(RFM95_REG_23_MAX_PAYLOAD_LENGTH, RFM95_MAX_PACKET_LEN); (void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY); - const modemConfig_t configuration = { MY_RFM95_MODEM_CONFIGRUATION }; + const rfm95_modemConfig_t configuration = { MY_RFM95_MODEM_CONFIGRUATION }; RFM95_setModemRegisters(configuration); - RFM95_setPreambleLength(8); // default + RFM95_setPreambleLength(RFM95_PREAMBLE_LENGTH); RFM95_setFrequency(frequency); // set power level RFM95_setTxPower(MY_RFM95_TX_POWER); @@ -134,17 +169,17 @@ LOCAL bool RFM95_initialise(const float frequency) { // RxDone, TxDone, CADDone is mapped to DI0 LOCAL void RFM95_interruptHandler(void) { // Read the interrupt register - const uint8_t irq_flags = RFM95_readReg(RFM95_REG_12_IRQ_FLAGS); - if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irq_flags & (RFM95_RX_TIMEOUT | RFM95_PAYLOAD_CRC_ERROR)) ) { + const uint8_t irqFlags = RFM95_readReg(RFM95_REG_12_IRQ_FLAGS); + if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irqFlags & (RFM95_RX_TIMEOUT | RFM95_PAYLOAD_CRC_ERROR)) ) { // CRC error or timeout // RXcontinuous mode: radio stays in RX mode, clearing IRQ needed } - else if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irq_flags & RFM95_RX_DONE)) { + else if (RFM95.radioMode == RFM95_RADIO_MODE_RX && (irqFlags & RFM95_RX_DONE)) { // set radio to STDBY (we are in RXcontinuous mode) (void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY); // Have received a packet //In order to retrieve received data from FIFO the user must ensure that ValidHeader, PayloadCrcError, RxDone and RxTimeout interrupts in the status register RegIrqFlags are not asserted to ensure that packet reception has terminated successfully(i.e.no flags should be set). - const uint8_t bufLen = min(RFM95_readReg(RFM95_REG_13_RX_NB_BYTES), RFM95_MAX_PACKET_LEN); + const uint8_t bufLen = min(RFM95_readReg(RFM95_REG_13_RX_NB_BYTES), (uint8_t)RFM95_MAX_PACKET_LEN); if (bufLen >= RFM95_HEADER_LEN) { // Reset the fifo read ptr to the beginning of the packet RFM95_writeReg(RFM95_REG_0D_FIFO_ADDR_PTR, RFM95_readReg(RFM95_REG_10_FIFO_RX_CURRENT_ADDR)); @@ -160,16 +195,16 @@ LOCAL void RFM95_interruptHandler(void) { } } - else if (RFM95.radioMode == RFM95_RADIO_MODE_TX && (irq_flags & RFM95_TX_DONE) ) { + else if (RFM95.radioMode == RFM95_RADIO_MODE_TX && (irqFlags & RFM95_TX_DONE) ) { (void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY); } - else if (RFM95.radioMode == RFM95_RADIO_MODE_CAD && (irq_flags & RFM95_CAD_DONE) ) { - RFM95.cad = irq_flags & RFM95_CAD_DETECTED; + else if (RFM95.radioMode == RFM95_RADIO_MODE_CAD && (irqFlags & RFM95_CAD_DONE) ) { + RFM95.cad = irqFlags & RFM95_CAD_DETECTED; (void)RFM95_setRadioMode(RFM95_RADIO_MODE_STDBY); } // Clear all IRQ flags - RFM95_writeReg(RFM95_REG_12_IRQ_FLAGS, 0xff); + RFM95_writeReg(RFM95_REG_12_IRQ_FLAGS, 0xFF); } LOCAL bool RFM95_available(void) { @@ -242,7 +277,7 @@ LOCAL bool RFM95_sendFrame(const uint8_t recipient, uint8_t* data, const uint8_t packet.header.sender = RFM95.address; packet.header.recipient = recipient; packet.header.controlFlags = 0x00; - packet.payloadLen = min(len, RFM95_MAX_PAYLOAD_LEN); + packet.payloadLen = min(len, (const uint8_t)RFM95_MAX_PAYLOAD_LEN); packet.header.controlFlags = flags; memcpy(&packet.payload, data, packet.payloadLen); return RFM95_send(packet); @@ -257,8 +292,8 @@ LOCAL void RFM95_setFrequency(const float centre) { LOCAL bool RFM95_setTxPower(uint8_t powerLevel) { // RFM95/96/97/98 does not have RFO pins connected to anything. Only PA_BOOST - powerLevel = max(RFM95_MIN_POWER_LEVEL_DBM, powerLevel); - powerLevel = min(RFM95_MAX_POWER_LEVEL_DBM, powerLevel); + powerLevel = max((uint8_t)RFM95_MIN_POWER_LEVEL_DBM, powerLevel); + powerLevel = min((uint8_t)RFM95_MAX_POWER_LEVEL_DBM, powerLevel); if (powerLevel != RFM95.powerLevel) { RFM95.powerLevel = powerLevel; uint8_t val; @@ -283,7 +318,7 @@ LOCAL bool RFM95_setTxPower(uint8_t powerLevel) { } // Sets registers from a canned modem configuration structure -LOCAL void RFM95_setModemRegisters(const modemConfig_t config) { +LOCAL void RFM95_setModemRegisters(const rfm95_modemConfig_t config) { RFM95_writeReg(RFM95_REG_1D_MODEM_CONFIG1, config.reg_1d); RFM95_writeReg(RFM95_REG_1E_MODEM_CONFIG2, config.reg_1e); RFM95_writeReg(RFM95_REG_26_MODEM_CONFIG3, config.reg_26); @@ -306,13 +341,13 @@ LOCAL uint8_t RFM95_getAddress(void) { LOCAL bool RFM95_isChannelActive(void) { (void)RFM95_setRadioMode(RFM95_RADIO_MODE_CAD); while (RFM95.radioMode == RFM95_RADIO_MODE_CAD) { - yield(); + doYield(); } return RFM95.cad; } -LOCAL bool RFM95_setRadioMode(const rfm95_radio_mode_t newRadioMode) { +LOCAL bool RFM95_setRadioMode(const rfm95_radioMode_t newRadioMode) { if (RFM95.radioMode == newRadioMode) { return false; } @@ -378,7 +413,8 @@ LOCAL bool RFM95_executeATC(const rfm95_RSSI_t currentRSSI, const rfm95_RSSI_t t return RFM95_setTxPower(RFM95.powerLevel);; } -LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer, const uint8_t bufferSize, const uint8_t retries, const uint32_t retryWaitTime) { +LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer, const uint8_t bufferSize, const uint8_t retries, const uint32_t retryWaitTime) +{ for (uint8_t retry = 0; retry < retries; retry++) { RFM95_DEBUG(PSTR("RFM95:SWR:SEND TO=%d,RETRY=%d\n"), recipient, retry); rfm95_flag_t flags = 0x00; @@ -390,7 +426,7 @@ LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer, cons return true; } const uint32_t enterMS = hwMillis(); - while (hwMillis() - enterMS < 500) { + while (hwMillis() - enterMS < retryWaitTime) { if (RFM95.rxBufferValid) { const uint8_t sender = RFM95.currentPacket.header.sender; const rfm95_sequenceNumber_t ACKsequenceNumber = RFM95.currentPacket.ACK.sequenceNumber; @@ -406,7 +442,7 @@ LOCAL bool RFM95_sendWithRetry(const uint8_t recipient, const void* buffer, cons return true; } // seq check } - yield(); + doYield(); } RFM95_DEBUG(PSTR("!RFM95:SWR:NACK\n")); if (RFM95.ATCenabled) { @@ -425,28 +461,22 @@ LOCAL bool RFM95_waitCAD(void) { if (hwMillis() - enterMS > RFM95_CAD_TIMEOUT_MS) { return false; } - yield(); + doYield(); } return true; } // Wait for any previous transmission to finish LOCAL bool RFM95_waitPacketSent(void) { - while (RFM95.radioMode == RFM95_RADIO_MODE_TX) - yield(); + while (RFM95.radioMode == RFM95_RADIO_MODE_TX) { + doYield(); + } return true; } LOCAL int16_t RFM95_getRSSI(void) { return (int16_t)(RFM95.currentPacket.RSSI - RFM95_RSSI_OFFSET); } -LOCAL int16_t RFM95_getSNR(void) { - return (int16_t)(RFM95.currentPacket.SNR / 4); -} - -LOCAL int8_t RFM95_getTxPower(void) { - return RFM95.powerLevel; -} LOCAL void RFM95_ATCmode(const bool OnOff, const int16_t targetRSSI) { RFM95.ATCenabled = OnOff; @@ -454,6 +484,7 @@ LOCAL void RFM95_ATCmode(const bool OnOff, const int16_t targetRSSI) { } LOCAL bool RFM95_sanityCheck(void) { + // not implemented yet return true; } diff --git a/drivers/RFM95/RFM95.h b/drivers/RFM95/RFM95.h index c9f253f..963fcf7 100644 --- a/drivers/RFM95/RFM95.h +++ b/drivers/RFM95/RFM95.h @@ -133,6 +133,8 @@ #define RFM95_RX_FIFO_ADDR (0x00u) //!< RX FIFO addr pointer #define RFM95_TX_FIFO_ADDR (0x80u) //!< TX FIFO addr pointer #define RFM95_MAX_PACKET_LEN (0x40u) //!< This is the maximum number of bytes that can be carried by the LORA +#define RFM95_PREAMBLE_LENGTH (8u) //!< Preamble length, default=8 + #define RFM95_CAD_TIMEOUT_MS (2*1000ul) //!< channel activity detection timeout #define RFM95_FXOSC (32000000.0f) //!< The crystal oscillator frequency of the module @@ -177,7 +179,7 @@ typedef enum { RFM95_RADIO_MODE_CAD = 2, //!< CAD mode RFM95_RADIO_MODE_SLEEP = 3, //!< SLEEP mode RFM95_RADIO_MODE_STDBY = 4 //!< STDBY mode -} rfm95_radio_mode_t; +} rfm95_radioMode_t; /** * @brief RFM95 modem config registers @@ -186,7 +188,7 @@ typedef struct { uint8_t reg_1d; //!< Value for register REG_1D_MODEM_CONFIG1 uint8_t reg_1e; //!< Value for register REG_1E_MODEM_CONFIG2 uint8_t reg_26; //!< Value for register REG_26_MODEM_CONFIG3 -} modemConfig_t; +} rfm95_modemConfig_t; /** * @brief Sequence number data type @@ -258,7 +260,7 @@ typedef struct { uint8_t powerLevel; //!< TX power level dBm uint8_t ATCtargetRSSI; //!< ATC: target RSSI // 8 bit - rfm95_radio_mode_t radioMode : 3; //!< current transceiver state + rfm95_radioMode_t radioMode : 3; //!< current transceiver state bool cad : 1; //!< RFM95_cad bool rxBufferValid : 1; //!< RX buffer valid bool ATCenabled : 1; //!< ATC enabled @@ -288,7 +290,7 @@ LOCAL uint8_t RFM95_getAddress(void); * bandwidth, spreading factor etc. * @param config See modemConfig_t and references therein */ -LOCAL void RFM95_setModemRegisters(const modemConfig_t config); +LOCAL void RFM95_setModemRegisters(const rfm95_modemConfig_t config); /** * @brief Tests whether a new message is available * @return True if a new, complete, error-free uncollected message is available to be retreived by @ref RFM95_recv() @@ -374,7 +376,7 @@ LOCAL bool RFM95_waitPacketSent(void); * @param newRadioMode * @return True if mode changed */ -LOCAL bool RFM95_setRadioMode(const rfm95_radio_mode_t newRadioMode); +LOCAL bool RFM95_setRadioMode(const rfm95_radioMode_t newRadioMode); /** * @brief Low level interrupt handler */ @@ -384,11 +386,6 @@ LOCAL void RFM95_interruptHandler(void); */ LOCAL void RFM95_clearRxBuffer(void); /** -* @brief RFM95_getSNR -* @return SNR Signal strength of last packet -*/ -LOCAL int16_t RFM95_getSNR(void); -/** * @brief RFM95_getRSSI * @return RSSI Signal strength of last packet */ @@ -401,11 +398,6 @@ LOCAL int16_t RFM95_getRSSI(void); */ LOCAL bool RFM95_executeATC(const rfm95_RSSI_t currentRSSI, const rfm95_RSSI_t targetRSSI); /** -* @brief RFM95_getTxPower -* @return Current power level -*/ -LOCAL int8_t RFM95_getTxPower(void); -/** * @brief RFM95_ATCmode * @param targetRSSI Target RSSI for transmitter (default -60) * @param OnOff True to enable ATC diff --git a/drivers/RPi/rpi_util.cpp b/drivers/RPi/rpi_util.cpp index 7ee1a92..0888554 100644 --- a/drivers/RPi/rpi_util.cpp +++ b/drivers/RPi/rpi_util.cpp @@ -44,6 +44,7 @@ struct ThreadArgs { int gpioPin; }; +volatile bool interruptsEnabled = true; static pthread_mutex_t intMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_t *threadIds[64] = {NULL}; @@ -152,7 +153,13 @@ void *interruptHandler(void *args) { (void)read (fd, &c, 1) ; lseek (fd, 0, SEEK_SET) ; // Call user function. - func(); + pthread_mutex_lock(&intMutex); + if (interruptsEnabled) { + pthread_mutex_unlock(&intMutex); + func(); + } else { + pthread_mutex_unlock(&intMutex); + } } close(fd); @@ -322,9 +329,13 @@ uint8_t rpi_util::digitalPinToInterrupt(uint8_t physPin) { } void rpi_util::interrupts() { + pthread_mutex_lock(&intMutex); + interruptsEnabled = true; pthread_mutex_unlock(&intMutex); } void rpi_util::noInterrupts() { pthread_mutex_lock(&intMutex); + interruptsEnabled = false; + pthread_mutex_unlock(&intMutex); } diff --git a/drivers/RPi/rpi_util.h b/drivers/RPi/rpi_util.h index 3d31eb9..f7447ba 100644 --- a/drivers/RPi/rpi_util.h +++ b/drivers/RPi/rpi_util.h @@ -45,10 +45,10 @@ typedef enum { } rpi_pinedge; typedef enum { - PIN_SPI_SS = RPI_GPIO_P1_24, - PIN_SPI_MOSI = RPI_GPIO_P1_19, - PIN_SPI_MISO = RPI_GPIO_P1_21, - PIN_SPI_SCK = RPI_GPIO_P1_23 + PIN_SPI_SS = 24, + PIN_SPI_MOSI = 19, + PIN_SPI_MISO = 21, + PIN_SPI_SCK = 23 } rpi_spipins; const uint8_t SS = PIN_SPI_SS; diff --git a/examples_linux/mysGateway.cpp b/examples_linux/mysgw.cpp similarity index 83% rename from examples_linux/mysGateway.cpp rename to examples_linux/mysgw.cpp index c94d482..7ada2f0 100644 --- a/examples_linux/mysGateway.cpp +++ b/examples_linux/mysgw.cpp @@ -5,8 +5,8 @@ * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * - * Created by Marcelo Aquino - * Copyleft (c) 2016, Marcelo Aquino + * Created by Henrik Ekblad + * Copyright (C) 2013-2016 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org @@ -67,15 +67,25 @@ // Note: MY_SIGNING_REQUEST_SIGNATURES must also be set //#define MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL +// Enables RF24 encryption (all nodes and gateway must have this enabled, and all must be +// personalized with the same AES key) +//#define MY_RF24_ENABLE_ENCRYPTION + #include -void setup() { +#define ARDUINO 100 +// This space is intended to be used to include arduino libraries + +#undef ARDUINO + +void setup() { + // Setup locally attached sensors } void presentation() { - // Present locally attached sensors here + // Present locally attached sensors here } void loop() { - // Send locally attached sensors data here + // Send locally attached sensors data here } diff --git a/hooks/pre-commit.sh b/hooks/pre-commit.sh new file mode 100644 index 0000000..bb725f0 --- /dev/null +++ b/hooks/pre-commit.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +OPTIONS="--options=.astylerc" + +RETURN=0 +ASTYLE=astyle +if [ $? -ne 0 ]; then + echo "[!] astyle not installed or not in current path. Unable to check source file format policy." >&2 + exit 1 +fi + +FILES=`git diff --name-only --diff-filter=ACMR | grep -E "\.(c|cpp|h|ino)$"` +for FILE in $FILES; do + $ASTYLE $OPTIONS < $FILE | cmp -s $FILE - + if [ $? -ne 0 ]; then + echo "[!] $FILE does not respect the agreed coding style." >&2 + RETURN=1 + fi +done + +if [ $RETURN -eq 1 ]; then + echo "" >&2 + echo "Make sure you have run astyle with the following options:" >&2 + echo $OPTIONS >&2 +fi + +exit $RETURN \ No newline at end of file diff --git a/initscripts/mysgateway.systemd b/initscripts/mysgw.systemd similarity index 76% rename from initscripts/mysgateway.systemd rename to initscripts/mysgw.systemd index 5b707c6..41e7279 100644 --- a/initscripts/mysgateway.systemd +++ b/initscripts/mysgw.systemd @@ -3,7 +3,7 @@ Description=MySensors Gateway daemon Requires=network.target [Service] -ExecStart=%gateway_dir%/mysGateway +ExecStart=%gateway_dir%/mysgw [Install] WantedBy=multi-user.target diff --git a/initscripts/mysgateway.sysvinit b/initscripts/mysgw.sysvinit similarity index 98% rename from initscripts/mysgateway.sysvinit rename to initscripts/mysgw.sysvinit index 5ca7e12..a511f05 100644 --- a/initscripts/mysgateway.sysvinit +++ b/initscripts/mysgw.sysvinit @@ -1,6 +1,6 @@ #! /bin/sh ### BEGIN INIT INFO -# Provides: mysGateway +# Provides: mysgw # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 @@ -15,7 +15,7 @@ # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin DESC="MySensors Gateway" -NAME=mysGateway +NAME=mysgw DAEMON=%gateway_dir%/$NAME DAEMON_ARGS="-b" PIDFILE=/var/run/$NAME.pid diff --git a/library.json b/library.json index d55c3e4..3d53533 100644 --- a/library.json +++ b/library.json @@ -1,13 +1,13 @@ { "name": "MySensors", "keywords": "framework, sensor, rf", - "description": "Home Automation Framework. Create your own wireless sensor mesh using NRF24L01+ and RFM69 radios running on Arduino or ESP8266. Over-the-air updates and MySensors support in 16+ home automation controllers.", + "description": "Home Automation Framework. Create your own wireless sensor mesh using NRF24L01+, RFM69 and RFM95 radios running on Arduino or ESP8266. Over-the-air updates and MySensors support in 16+ home automation controllers.", "repository": { "type": "git", "url": "https://github.com/mysensors/MySensors.git" }, - "version": "2.0.1-beta", + "version": "2.1.0-beta", "frameworks": "arduino", "platforms": [ "atmelavr", diff --git a/library.properties b/library.properties index 9d945cd..f0d927c 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=MySensors -version=2.0.1-beta +version=2.1.0-beta author=The MySensors Team maintainer=The MySensors Team sentence=Home Automation Framework -paragraph=Create your own wireless sensor mesh using NRF24L01+ and RFM69 radios running on Arduino, SAMD and ESP8266. Allows over-the-air updates of nodes. Supported by 20+ home automation controllers. +paragraph=Create your own wireless sensor mesh using NRF24L01+, RFM69 and RFM95 radios running on Arduino, SAMD and ESP8266. Allows over-the-air updates of nodes. Supported by 20+ home automation controllers. category=Communication url=https://www.mysensors.org architectures=avr,esp8266,samd diff --git a/tests/Arduino/sketches/hard_signing_whitelisting_full_debug_rfm95_rsa/hard_signing_whitelisting_full_debug_rfm95_rsa.ino b/tests/Arduino/sketches/hard_signing_whitelisting_full_debug_rfm95_rsa/hard_signing_whitelisting_full_debug_rfm95_rsa.ino new file mode 100644 index 0000000..510c72c --- /dev/null +++ b/tests/Arduino/sketches/hard_signing_whitelisting_full_debug_rfm95_rsa/hard_signing_whitelisting_full_debug_rfm95_rsa.ino @@ -0,0 +1,38 @@ +/* + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2016 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + */ +#include +#include +#define MY_DEBUG +#define MY_DEBUG_VERBOSE_SIGNING +#define MY_RADIO_RFM95 +//#define MY_SIGNING_SOFT +#define MY_SIGNING_ATSHA204 +#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}} +#define MY_SIGNING_REQUEST_SIGNATURES +#ifndef MY_SIGNING_SOFT_RANDOMSEED_PIN +#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 +#endif +#ifndef MY_SIGNING_ATSHA204_PIN +#define MY_SIGNING_ATSHA204_PIN 17 +#endif +#define MY_RFM69_ENABLE_ENCRYPTION + +#include