Skip to content

Commit

Permalink
Merge pull request #41 from devicehive/develop
Browse files Browse the repository at this point in the history
v0.8
  • Loading branch information
Nikolay-Kha authored Nov 23, 2017
2 parents fa0a124 + 167c5bd commit 04c5d37
Show file tree
Hide file tree
Showing 23 changed files with 349 additions and 198 deletions.
28 changes: 21 additions & 7 deletions DeviceHiveESP8266.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Table of contents
* [Overview](#overview)
* [Getting started](#getting-started)
* [SSL support](#ssl-support)
* [Local services](#local-services)
* [mDNS](#mdns)
* [RESTful API](#restful-api)
Expand Down Expand Up @@ -151,6 +152,18 @@ After rebooting you can send commands to DeviceHive server or local RESTful API

Now you can start writing your own program to create your own IoT devices with your favorite language and frameworks using DeviceHive [RESTful API](http://devicehive.com/restful) which you can transmitted with HTTP(S) or Websockets. List of accepted command for ESP8266 is listed in this document.

# SSL support
Firmware supports encrypted WebSocket server connectity using Transport Layer Security (TLS). Server should support TLSv1.1 and TLS_RSA_WITH_AES_128_CBC_SHA or TLS_RSA_WITH_AES_256_CBC_SHA cipher.

Please note, chip has 2 KB buffer for secure data, so ssl handshake should not be more otherwise connection reset would occur. To check size of the handshake, run this command:
```
openssl s_client -connect devicehive.com:443 -tls1
```
and check in the output line with handshake size:
```
SSL handshake has read 4796 bytes and written 336 bytes
```

# Local services
Firmware sets chip hostname and announce chip with mDNS using configured DeviceId. Hostname is limited with 32 chars, further DeiviceId's chars are omitted.

Expand Down Expand Up @@ -231,7 +244,9 @@ This is auxiliary command that is used to get a list of supported commands. This
and output looks like:

```json
[
{
"commands":
[
"gpio/write",
"gpio/read",
"gpio/int",
Expand All @@ -243,7 +258,8 @@ and output looks like:
"uart/int",
"uart/terminal",
...
]
]
}
```

The `command/list` command is used on the `tryapi.html` page to provide command suggestion.
Expand Down Expand Up @@ -355,7 +371,6 @@ JSON with a set of key-value pairs, where key is pin number and value is one of
*Example*:
```json
{
"all":"read",
"0":"read"
}
```
Expand All @@ -376,8 +391,7 @@ Json with set of key-value, where key is ADC channel and value is period in mill
*Example*:
```json
{
"0":"1000",
"0":"disable"
"0":"1000"
}
```

Expand Down Expand Up @@ -529,7 +543,7 @@ Return "OK" in status and json like below in result on success. Or "Error" and d
Write data to I2C bus.

*Parameters*:
* "address" - I2C slave device address, decimal integer value.
* "address" - I2C slave device address, hex value. Can start with "0x".
* "data" - base64 encoded data that should be sent. Maximum size of data is 264 bytes.
* "SDA" - GPIO port number for SDA data line. If not specified, previous pin will be used. Default is "0".
* "SCL" - GPIO port number for SCL data line. If not specified, previous pin will be used. Default is "2".
Expand All @@ -539,7 +553,7 @@ Write data to I2C bus.
{
"SDA":"4",
"SCL":"5",
"address":"122",
"address":"78",
"data":"YWI="
}
```
Expand Down
9 changes: 6 additions & 3 deletions esp-utils/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CXX ?= g++
CFLAGS += -c -Wall
LDFLAGS += -s -Os
LDFLAGS += -Os
LIBS =
OBJDIR = build
SOURCES = $(wildcard common/*.cpp)
Expand All @@ -10,9 +10,12 @@ ALLOBJECTS = $(COMMONOBJECTS) $(addprefix $(OBJDIR)/, $(MAINS:%.cpp=%.o))
ESPTERMINAL = $(OBJDIR)/esp-terminal
ESPFLASHER = $(OBJDIR)/esp-flasher
ifeq ($(OS),Windows_NT)
LDFLAGS +=-static
LDFLAGS += -static -s
else
LIBS = -pthread
ifneq ($(shell uname -s),Darwin)
LDFLAGS += -s
LIBS = -pthread
endif
endif

all: $(SOURCES) $(ESPTERMINAL) $(ESPFLASHER)
Expand Down
4 changes: 2 additions & 2 deletions esp-utils/common/serialport_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ SerialPort *SerialPort::open(const char *port) {
cfsetispeed(&tio,B115200);

tcflush(comp, TCIOFLUSH);

if( tcsetattr ( comp, TCSANOW, &tio ) != 0) {
if( tcsetattr(comp, TCSANOW, &tio) != 0) {
close(comp);
return 0;
}
tcflush(comp, TCIOFLUSH);

SerialPort *comport = new SerialPort(comp, port);
pthread_t thr;
Expand Down
31 changes: 22 additions & 9 deletions esp-utils/esp-flasher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@

#define ESP_BLOCK_SIZE 0x400
#define ESP_SECTOR_SIZE 0x1000
#define AUTODETECT_TIMEOUT 1000
#define AUTODETECT_TIMEOUT 500
#define FLASHING_TIMEOUT 5000
#define AUTODETECT_MAX_PORT 20
#define AUTODETECT_MAX_SYNC_ATTEMPS 3
#define MAX_SYNC_ATTEMPS 3
#define CHECK_BOOT_MODE_NOTIFY "Make sure that GPIO0 and GPIO15 are connected to low-level(ground),\r\n" \
"GPIO2 and CH_PD are connected to high-level(power source)\r\n" \
"And reboot device(reconnect power or connect RST pin to ground for a second).\r\n"
Expand Down Expand Up @@ -370,12 +371,14 @@ bool flash_sync(SerialPort *port, bool printErrors) {
rh.command = 0x08; // sync
rh.size = htole16(sizeof(body));
rh.cs = esp_checksum((void*)body, sizeof(body));
if(!flash_send(port, &rh, (void*)body, printErrors)) {
if(printErrors)
printf("\r\nFailed to sync device\r\n");
return false;
for(int i=0; i < MAX_SYNC_ATTEMPS; i++) {
if(flash_send(port, &rh, (void*)body, false)) {
return true;
}
}
return true;
if(printErrors)
printf("\r\nFailed to sync device\r\n");
return false;
}

bool startWith(const char *str, const char *start) {
Expand Down Expand Up @@ -407,6 +410,7 @@ void force_flash_mode(SerialPort *port) {
port->setRts(false);
port->sleep(50);
port->setDtr(false);
port->sleep(100); //wait till chip boots
}

void reboot(SerialPort *port) {
Expand Down Expand Up @@ -444,12 +448,22 @@ int main(int argc, char* argv[]) {
}
}
if(port) {
if(!flash_sync(port, true)) {
TIMEOUT = AUTODETECT_TIMEOUT;
bool synced = false;
for (int i=0; i < AUTODETECT_MAX_SYNC_ATTEMPS; i++) {
force_flash_mode(port);
if(flash_sync(port, false)) {
synced = true;
break;
}
}
if (!synced) {
delete port;
printf( "Device is not connected to UART or not in boot mode.\r\n" \
CHECK_BOOT_MODE_NOTIFY"\r\n");
return exit();
}
TIMEOUT = FLASHING_TIMEOUT;
} else {
TIMEOUT = AUTODETECT_TIMEOUT;
printf("Detecting device...\r\n");
Expand All @@ -468,12 +482,11 @@ int main(int argc, char* argv[]) {
}
if (ports[i]) {
mCurrentPort = ports[i];
force_flash_mode(ports[i]);
if (flash_sync(ports[i], false)) {
printf("Device found on %s and successfully synced\r\n", ports[i]->getName());
port = ports[i];
}
if(j == 0 && port == NULL)
force_flash_mode(ports[i]);
mCurrentPort = NULL;
}
}
Expand Down
3 changes: 2 additions & 1 deletion firmware-src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ TARGETAR = $(OBJDIR)/devicehive.a
TARGETELF = $(OBJDIR)/devicehive.elf
INCLUDEDIRS = $(addprefix -I,$(SDKPATH)/include $(CURDIR)/sources)
LIBDIR = $(addprefix -L,$(SDKPATH)/lib)
LIBS = $(addprefix -l,c gcc phy pp net80211 lwip wpa main json crypto)
LIBS = $(addprefix -l,c gcc phy pp net80211 lwip wpa main json crypto ssl)
SOURCES = $(wildcard sources/*.c) $(wildcard drivers/*.c) $(wildcard sources/devices/*.c) $(wildcard sources/DH/*.c) $(wildcard sources/commands/*.c)
OBJECTS = $(addprefix $(OBJDIR)/, $(SOURCES:%.c=%.o))
GITVER = $(shell git rev-parse HEAD 2> /dev/null || echo \"not a git repo\")
Expand All @@ -24,6 +24,7 @@ AR = $(CROSS_COMPILE)ar
SIZE = $(CROSS_COMPILE)size
PAGESH = pages/pages.h


.PHONY: all flash full_flash terminal clean disassemble reboot

all: $(FIRMWARE)
Expand Down
2 changes: 1 addition & 1 deletion firmware-src/pages/gen_pages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ for file in $FILE_LIST; do
filename=$(basename "$file")
echo "Parsing $filename ..."
name=${filename/./_}
data=$(od -An -v -t x1 $file|tr -d '\n' | sed -E "s/( +)([[:xdigit:]]{2})/\\\x\2/g")
data=$(gzip -c $file | od -An -v -t x1 | tr -d '\n' | sed -E "s/( +)([[:xdigit:]]{2})/\\\x\2/g")
print "RO_DATA char $name[] = \"$data\";"
index="$index$comma {\"$filename\", $name, sizeof($name) - 1}"
comma=", "
Expand Down
8 changes: 4 additions & 4 deletions firmware-src/sources/DH/onewire.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ unsigned int ICACHE_FLASH_ATTR dh_onewire_get_pin(void)
* @brief Reset onewire bus.
* @return Non-zero if device is presented. Zero otherwise.
*/
int ICACHE_FLASH_ATTR dh_onewire_reset(DHGpioPinMask pin_mask, int exit_on_presence)
int ICACHE_FLASH_ATTR dh_onewire_reset(DHGpioPinMask pin_mask, int reset_time_us, int exit_on_presence)
{
system_soft_wdt_feed();
const int pinstate = (gpio_input_get() & pin_mask) !=0;
Expand All @@ -91,7 +91,7 @@ int ICACHE_FLASH_ATTR dh_onewire_reset(DHGpioPinMask pin_mask, int exit_on_prese

// send RESET
gpio_output_set(0, pin_mask, pin_mask, 0);
os_delay_us(ONEWIRE_RESET_LENGHT_US);
os_delay_us(reset_time_us);
gpio_output_set(pin_mask, 0, pin_mask, 0);

// check RESPONSE
Expand Down Expand Up @@ -169,7 +169,7 @@ int ICACHE_FLASH_ATTR dh_onewire_write(const void *buf_, size_t len)
lock_int();

const DHGpioPinMask pin_mask = DH_GPIO_PIN(mOneWirePin);
int present = dh_onewire_reset(pin_mask, 0);
int present = dh_onewire_reset(pin_mask, ONEWIRE_RESET_LENGHT_US, 0);
if (!present) {
unlock_int();
return -1; // failed
Expand Down Expand Up @@ -241,7 +241,7 @@ int ICACHE_FLASH_ATTR dh_onewire_search(void *buf_, size_t *len, int command, un
lock_int();

do {
if (!dh_onewire_reset(pin_mask, 0)) {
if (!dh_onewire_reset(pin_mask, ONEWIRE_RESET_LENGHT_US, 0)) {
unlock_int();
if (lastAmbiguity == 8*sizeof(address)) {
*len = 0; // devices are not connected
Expand Down
3 changes: 2 additions & 1 deletion firmware-src/sources/DH/onewire.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ unsigned int dh_onewire_get_pin(void);
* @brief Reset onewire bus.
* @param[in] pin_mask Pin mask to reset.
* @param[in] exit_on_presence Flag to exit immediately if device found.
* @param[in] reset_time_us reset signal length.
* @return Non-zero if device is presented. Zero otherwise.
*/
int dh_onewire_reset(DHGpioPinMask pin_mask, int exit_on_presence);
int dh_onewire_reset(DHGpioPinMask pin_mask, int reset_time_us, int exit_on_presence);


/**
Expand Down
24 changes: 12 additions & 12 deletions firmware-src/sources/base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,25 @@ static inline int ICACHE_FLASH_ATTR base64_table(uint32_t reg, int offset)


/*
* base64_encode_length() implementation.
* esp_base64_encode_length() implementation.
*/
size_t ICACHE_FLASH_ATTR base64_encode_length(size_t data_len)
size_t ICACHE_FLASH_ATTR esp_base64_encode_length(size_t data_len)
{
return (data_len + 2)/3 * 4; // round_up(len/3)*4
}


/*
* base64_encode() implementation.
* esp_base64_encode() implementation.
*/
int ICACHE_FLASH_ATTR base64_encode(const void *data_, size_t data_len,
char *text, size_t text_len)
int ICACHE_FLASH_ATTR esp_base64_encode(const void *data_, size_t data_len,
char *text, size_t text_len)
{
if (!data_len)
return 0; // nothing to encode

// check we have enough space for output
if (base64_encode_length(data_len) > text_len)
if (esp_base64_encode_length(data_len) > text_len)
return 0;

const uint8_t *data = (const uint8_t*)data_;
Expand Down Expand Up @@ -97,9 +97,9 @@ int ICACHE_FLASH_ATTR base64_encode(const void *data_, size_t data_len,


/*
* base64_decode_length() implementation.
* esp_base64_decode_length() implementation.
*/
size_t ICACHE_FLASH_ATTR base64_decode_length(const char *text, size_t text_len)
size_t ICACHE_FLASH_ATTR esp_base64_decode_length(const char *text, size_t text_len)
{
if (!text_len)
return 0; // nothing to decode
Expand All @@ -117,16 +117,16 @@ size_t ICACHE_FLASH_ATTR base64_decode_length(const char *text, size_t text_len)


/*
* base64_decode() implementation.
* esp_base64_decode() implementation.
*/
int ICACHE_FLASH_ATTR base64_decode(const char *text, size_t text_len,
void *data_base, size_t data_len)
int ICACHE_FLASH_ATTR esp_base64_decode(const char *text, size_t text_len,
void *data_base, size_t data_len)
{
if (!text_len || text_len%4)
return 0; // nothing to decode

// check we have enough space for output
if (base64_decode_length(text, text_len) > data_len)
if (esp_base64_decode_length(text, text_len) > data_len)
return 0;

uint8_t *data = (uint8_t*)data_base;
Expand Down
20 changes: 10 additions & 10 deletions firmware-src/sources/base64.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@
* @param[in] text_len Output buffer length in bytes.
* @return Number of bytes written to output buffer.
*/
int base64_encode(const void *data,
size_t data_len,
char *text,
size_t text_len);
int esp_base64_encode(const void *data,
size_t data_len,
char *text,
size_t text_len);


/**
* @brief Estimate how many bytes will take `Base64` encoded data.
* @param[in] data_len Binary data length in bytes.
* @return `Base64` encoded text length in bytes.
*/
size_t base64_encode_length(size_t data_len);
size_t esp_base64_encode_length(size_t data_len);


/**
Expand All @@ -47,10 +47,10 @@ size_t base64_encode_length(size_t data_len);
* @param[in] data_len Output buffer length in bytes.
* @return Number of bytes written to output buffer.
*/
int base64_decode(const char *text,
size_t text_len,
void *data,
size_t data_len);
int esp_base64_decode(const char *text,
size_t text_len,
void *data,
size_t data_len);


/**
Expand All @@ -62,6 +62,6 @@ int base64_decode(const char *text,
* @param[in] text_len Encoded text length in bytes.
* @return Decoded binary data length in bytes.
*/
size_t base64_decode_length(const char *text, size_t text_len);
size_t esp_base64_decode_length(const char *text, size_t text_len);

#endif /* _DATAENCODEBASE64_H_ */
Loading

0 comments on commit 04c5d37

Please sign in to comment.