Skip to content

Add early detection of closed stream in lwmqtt_arduino_network_read #179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 2, 2019
Merged

Add early detection of closed stream in lwmqtt_arduino_network_read #179

merged 1 commit into from
Dec 2, 2019

Conversation

dzindra
Copy link
Contributor

@dzindra dzindra commented Nov 29, 2019

When underlying Client instance is closed or errors out, readBytes method still waits for timeout. This can be problematic especially when connecting to server with longer timeouts intervals.

This PR adds read error detection and early return for lwmqtt_arduino_network_read method. Other behaviour is unchanged (ie still tries to read as many bytes as possible until timeout is reached and considers 0 bytes read as error).

@256dpi
Copy link
Owner

256dpi commented Dec 1, 2019

Thanks for the contribution!

Do you know why readBytes does not immediately return when the connection has been closed? There is no data to be read anyway. Seems to me that this is a bug and it should be fixed at the source.

@dzindra
Copy link
Contributor Author

dzindra commented Dec 2, 2019

readBytes is inherited from Stream class and this class does not have open/closed state (it is basically for Serial streams). Open/closed state is added by Client class and most Client implementations do not override Stream::timedRead to add this check.

@256dpi
Copy link
Owner

256dpi commented Dec 2, 2019

Thanks for the explanation, it makes sense to me now!

@256dpi 256dpi merged commit 2c4f12c into 256dpi:master Dec 2, 2019
@256dpi
Copy link
Owner

256dpi commented Dec 5, 2019

Unfortunately, this didn't work as expected... Most Arduino cores do also return an error if there has been no data read, but the connection is still alive (see the example below). I fixed the regression by simply ignoring non positive return values and calling client->connected() to check if the connection is still alive (see fbe67fc).

// WiFi101/src/WiFiClient.cpp
int WiFiClient::read(uint8_t* buf, size_t size)
{
	// sizeof(size_t) is architecture dependent
	// but we need a 16 bit data type here
	uint16_t size_tmp = available();
	
	if (size_tmp == 0) {
		return -1;
	}
	
	if (size < size_tmp) {
		size_tmp = size;
	}

	for (uint32_t i = 0; i < size_tmp; ++i) {
		buf[i] = _buffer[_tail++];
	}
	
	if (_tail == _head) {
		_tail = _head = 0;
		_flag &= ~SOCKET_BUFFER_FLAG_FULL;
		recv(_socket, _buffer, SOCKET_BUFFER_MTU, 0);
		m2m_wifi_handle_events(NULL);
	}

	return size_tmp;
}

@dzindra
Copy link
Contributor Author

dzindra commented Dec 6, 2019

Oh, sorry about that, I've tested this with SAMD core and few client implementations, however none returned -1 but 0. Unfortunately the documentation for Client::read(buf,size) is missing, so no definitive truth there.

Your solution works well with the issue I was facing so thank you and sorry for the trouble.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants