Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
## 6.3.0

### FEATURES

- New cloud event API that supports sending and receiving up to 16K of data in an event [#2840](https://github.com/particle-iot/device-os/pull/2840)
- Electron 2 platform support [#2844](https://github.com/particle-iot/device-os/pull/2844)

### ENHANCEMENTS
- [wiring] Generate an error when using `EEPROM` with `String` objects as `String` contains dynamically allocated data on heap [#2855](https://github.com/particle-iot/device-os/pull/2855)
- [network] Postpone `Ethernet` interface initialization to allow STARTUP() call to override pin configuration without a reset [#2848](https://github.com/particle-iot/device-os/pull/2848)

### BUGFIXES

- Prevent low-level WiFI network buffer overflow [#2853](https://github.com/particle-iot/device-os/pull/2853)
- [Gen 3] Increase main stack size from 2K to 4K [#2851](https://github.com/particle-iot/device-os/pull/2851)
- Thread-safe `__cxa_guard_acquire`/`__cxa_guard_release` implementation [#2851](https://github.com/particle-iot/device-os/pull/2851)
- [build] Fix section size calculations for paths containing section-like names [#2852](https://github.com/particle-iot/device-os/pull/2852)

### INTERNAL
- [test] wiring/no_fixture_long_running: update network tests to stress test large packets up to MTU size once max MTU is figured out [#2855](https://github.com/particle-iot/device-os/pull/2855)
- [test] communication/long_publish: adds a long running publish test [#2854](https://github.com/particle-iot/device-os/pull/2854)
- [build] Add asserts to linker files to make sure that stack sizes match the expected values [#2851](https://github.com/particle-iot/device-os/pull/2851)
- Stub `atexit` to free up flash space used by global object destructors [#2851](https://github.com/particle-iot/device-os/pull/2851)

## 6.2.1

### FEATURES
Expand Down
2 changes: 1 addition & 1 deletion build/release.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
set -o errexit -o pipefail -o noclobber -o nounset

VERSION=${VERSION:="6.3.0-rc.1"}
VERSION=${VERSION:="6.3.0"}

function display_help ()
{
Expand Down
4 changes: 2 additions & 2 deletions build/version.mk
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
VERSION_STRING = 6.3.0-rc.1
VERSION_STRING = 6.3.0

# PRODUCT_FIRMWARE_VERSION reported by default
# FIXME: Unclear if this is used, PRODUCT_FIRMWARE_VERSION defaults to 65535 every release
VERSION = 6300
VERSION = 6302

CFLAGS += -DSYSTEM_VERSION_STRING=$(VERSION_STRING)
3 changes: 3 additions & 0 deletions communication/inc/dtls_session_persist.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ class __attribute__((packed)) SessionPersistOpaque : public SessionPersistData
void clear_use_count() { use_counter = 0; }
int use_count() { return use_counter; }
bool has_expired() { return use_counter >= MAXIMUM_SESSION_USES; }
void set_use_count_once() {
use_counter = MAXIMUM_SESSION_USES;
}

static const int MAXIMUM_SESSION_USES = 3;
};
Expand Down
3 changes: 2 additions & 1 deletion communication/inc/spark_protocol_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ namespace ProtocolCommands {
WAKE = 1, // Deprecated, use PING instead
DISCONNECT = 2,
TERMINATE = 3,
PING = 4
PING = 4,
MOVE_CONNECTION = 5
};
};

Expand Down
11 changes: 9 additions & 2 deletions communication/src/dtls_message_channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,10 +575,17 @@ ProtocolError DTLSMessageChannel::command(Command command, void* arg)
reset_session();
return IO_ERROR_DISCARD_SESSION; //force re-establish

case MOVE_SESSION:
case MOVE_SESSION: {
bool once = false;
if (arg && *((bool*)arg)) {
once = true;
}
move_session = true;
if (once) {
sessionPersist.set_use_count_once();
}
break;

}
case LOAD_SESSION:
sessionPersist.restore(callbacks.restore);
break;
Expand Down
9 changes: 9 additions & 0 deletions communication/src/dtls_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ class DTLSProtocol : public Protocol
}
return r;
}
case ProtocolCommands::MOVE_CONNECTION: {
LOG(INFO, "Moving connection (session move + ping)");
int r = ProtocolError::NO_ERROR;
bool once = true; // Use session only once, if migration fails it will be invalidated immediately
if (!(r = channel.command(Channel::MOVE_SESSION, &once))) {
return this->command(ProtocolCommands::PING, 0, nullptr);
}
return r;
}
default:
return ProtocolError::UNKNOWN;
}
Expand Down
2 changes: 1 addition & 1 deletion modules/shared/system_module_version.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Skip to next 100 every v0.x.0 release (e.g. 108 for v0.6.2 to 200 for v0.7.0-rc.1)
# Bump by 1 for every prerelease or release with the same v0.x.* base.
COMMON_MODULE_VERSION ?= 6300
COMMON_MODULE_VERSION ?= 6302
SYSTEM_PART1_MODULE_VERSION ?= $(COMMON_MODULE_VERSION)

RELEASE_080_MODULE_VERSION_BASE ?= 300
Expand Down
6 changes: 5 additions & 1 deletion system/inc/system_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ extern "C" {
#define SYSTEM_VERSION_v620 SYSTEM_VERSION_DEFAULT(6, 2, 0)
#define SYSTEM_VERSION_v621 SYSTEM_VERSION_DEFAULT(6, 2, 1)
#define SYSTEM_VERSION_v630RC1 SYSTEM_VERSION_RC(6, 3, 0, 1)
#define SYSTEM_VERSION SYSTEM_VERSION_v630RC1
#define SYSTEM_VERSION_v630RC2 SYSTEM_VERSION_RC(6, 3, 0, 2)
#define SYSTEM_VERSION_v630 SYSTEM_VERSION_DEFAULT(6, 3, 0)
#define SYSTEM_VERSION SYSTEM_VERSION_v630

/**
* Previously we would set the least significant byte to 0 for the final release, but to make
Expand Down Expand Up @@ -415,6 +417,8 @@ extern "C" {
#define SYSTEM_VERSION_620
#define SYSTEM_VERSION_621
#define SYSTEM_VERSION_630RC1
#define SYSTEM_VERSION_630RC2
#define SYSTEM_VERSION_630

typedef struct __attribute__((packed)) SystemVersionInfo
{
Expand Down
19 changes: 19 additions & 0 deletions system/src/system_cloud_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,22 @@ int system_cloud_get_inet_family_keepalive(int af, unsigned int* value) {

return 0;
}

int system_cloud_move_connection(network_handle_t network) {
if (system_cloud_is_connected(nullptr)) { // XXX: this is not a bool!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😅

return SYSTEM_ERROR_INVALID_STATE;
}

LOG(INFO, "Attempting to move cloud connection to interface %u", network);

int r = system_cloud_rebind(network);
if (r) {
LOG(WARN, "Cloud connection rebind to %u failed err=%d", network, r);
return r;
}
r = spark_protocol_command(spark_protocol_instance(), ProtocolCommands::MOVE_CONNECTION);
if (r) {
LOG(WARN, "Protocol connection move failed err=%d", r);
}
return r;
}
3 changes: 3 additions & 0 deletions system/src/system_cloud_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#if HAL_PLATFORM_IFAPI
#include "netdb_hal.h"
#endif // HAL_PLATFORM_IFAPI
#include "system_network.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -53,6 +54,8 @@ int system_multicast_announce_presence(void* reserved);
int system_cloud_set_inet_family_keepalive(int af, unsigned int value, int flags);
int system_cloud_get_inet_family_keepalive(int af, unsigned int* value);
sock_handle_t system_cloud_get_socket_handle();
int system_cloud_move_connection(network_handle_t network);
int system_cloud_rebind(network_handle_t network);

#if HAL_PLATFORM_IFAPI
int system_cloud_resolv_address(int protocol, const ServerAddress* address, sockaddr* saddrCache, addrinfo** info, CloudServerAddressType* type, bool useCachedAddrInfo);
Expand Down
3 changes: 3 additions & 0 deletions system/src/system_cloud_connection_compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,5 +328,8 @@ sock_handle_t system_cloud_get_socket_handle()
return s_state.socket;
}

int system_cloud_rebind(network_handle_t network) {
return SYSTEM_ERROR_NOT_SUPPORTED;
}

#endif /* !HAL_USE_SOCKET_HAL_POSIX && HAL_USE_SOCKET_HAL_COMPAT */
23 changes: 23 additions & 0 deletions system/src/system_cloud_connection_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,4 +382,27 @@ sock_handle_t system_cloud_get_socket_handle()
return s_state.socket;
}

int system_cloud_rebind(network_handle_t network) {
if (s_state.socket < 0) {
return SYSTEM_ERROR_INVALID_STATE;
}

if (network == NETWORK_INTERFACE_ALL) {
return SYSTEM_ERROR_INVALID_ARGUMENT;
}

// Bind to specific netif
struct ifreq ifr = {};
if_index_to_name(network, ifr.ifr_name);

auto sockOptRet = sock_setsockopt(s_state.socket, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr));
if (sockOptRet) {
LOG(WARN, "Failed to bind cloud socket to interface %u error: %d", network, sockOptRet);
} else {
LOG(INFO, "Re-bound cloud socket to iface %u (\"%s\")", network, ifr.ifr_name);
}

return !sockOptRet ? SYSTEM_ERROR_NONE : SYSTEM_ERROR_NETWORK;
}

#endif /* HAL_USE_SOCKET_HAL_POSIX */
9 changes: 9 additions & 0 deletions system/src/system_connection_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,15 @@ int ConnectionManager::checkCloudConnectionNetwork() {
}
// If best candidate doesn't match current network interface - reconnect
LOG(TRACE, "Best network interface for cloud connection changed (to %s) - move the cloud session", netifToName(best));
if (best != NETWORK_INTERFACE_ALL) {
int r = system_cloud_move_connection(best);
if (!r) {
return 0;
} else {
LOG(WARN, "Failed to move connection err=%d, fallback to reconnect", r);
}
}
// Fallback to disconnect/connect
auto options = CloudDisconnectOptions().reconnect(true);
auto systemOptions = options.toSystemOptions();
spark_cloud_disconnect(&systemOptions, nullptr);
Expand Down
2 changes: 2 additions & 0 deletions system/system-versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@
| 3100 | 6200 | 6.2.0 | Argon, Boron, B SoM, B5 SoM, Tracker, Tracker M, E Som X, M SoM, P2 |
| 3101 | 6201 | 6.2.1 | Argon, Boron, B SoM, B5 SoM, Tracker, Tracker M, E Som X, M SoM, P2 |
| 3101 | 6300 | 6.3.0-rc.1 | Argon, Boron, B SoM, B5 SoM, Tracker, Tracker M, E Som X, M SoM, P2 |
| 3101 | 6301 | 6.3.0-rc.2 | Argon, Boron, B SoM, B5 SoM, Tracker, Tracker M, E Som X, M SoM, P2 |
| 3101 | 6302 | 6.3.0 | Argon, Boron, B SoM, B5 SoM, Tracker, Tracker M, E Som X, M SoM, P2 |

[1] For 0.8.0-rc.1, The v101 bootloader was also released in the Github releases as v200. Thus the next released bootloader in the 0.8.x line should be v201. As of 4/5/2018: 22 device had v200 bootloaders.

Expand Down
18 changes: 10 additions & 8 deletions user/tests/integration/slo/connect_time/connect_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,16 @@ DEFINE_WARM_BOOT_TEST(08)

test(publish_and_validate_stats) {
#if Wiring_Cellular
Cellular.on();
assertTrue(waitFor(network().isOn, TEST_MAX_TIMEOUT));
// Exclude 2G and non-production devices from the SLO validation
CellularDevice devInfo = {};
devInfo.size = sizeof(devInfo);
assertEqual(cellular_device_info(&devInfo, nullptr), 0);
if (devInfo.dev == DEV_SARA_G350 || devInfo.dev == DEV_QUECTEL_EG91_NA) {
stats.excludeFromSloValidation = true;
if (network() == Cellular) {
Cellular.on();
assertTrue(waitFor(network().isOn, TEST_MAX_TIMEOUT));
// Exclude 2G and non-production devices from the SLO validation
CellularDevice devInfo = {};
devInfo.size = sizeof(devInfo);
assertEqual(cellular_device_info(&devInfo, nullptr), 0);
if (devInfo.dev == DEV_SARA_G350 || devInfo.dev == DEV_QUECTEL_EG91_NA) {
stats.excludeFromSloValidation = true;
}
}
#endif // Wiring_Cellular
const size_t n = serializeStatsAsJson(nullptr /* buf */, 0 /* size */);
Expand Down