Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: TlsMQTTClient.cpp
- Revision:
- 1:5a896191c3c4
- Parent:
- 0:b32fa0c757d7
- Child:
- 3:0a48c984e15b
--- a/TlsMQTTClient.cpp Tue May 09 13:16:48 2017 +0000
+++ b/TlsMQTTClient.cpp Fri May 12 11:49:58 2017 +0000
@@ -17,6 +17,7 @@
logError("tcp connection failed");
goto fail;
}
+ tcp->set_blocking(false, 50);
// setup SSL context
ctx = CyaSSL_CTX_new((CYASSL_METHOD *)CyaSSLv23_client_method());
@@ -40,18 +41,26 @@
// setup SSL operations
ssl = CyaSSL_new(ctx);
+ CyaSSL_set_using_nonblock(ssl, 1);
CyaSSL_SetIOReadCtx(ssl, this);
CyaSSL_SetIORecv(ctx, ioRecv);
CyaSSL_SetIOWriteCtx(ssl, this);
CyaSSL_SetIOSend(ctx, ioSend);
// SSL connect
- {
+ while (true) {
int ret = CyaSSL_connect(ssl);
+
+ if (ret != SSL_SUCCESS) {
+ int err = CyaSSL_get_error(ssl, ret);
- if (ret != SSL_SUCCESS) {
- logError("SSL_connect failed");
- int err = CyaSSL_get_error(ssl, ret);
+ if (SSL_ERROR_WANT_READ == err ||
+ SSL_ERROR_WANT_WRITE == err) {
+ continue;
+ }
+
+ logError("SSL_connect failed ret %d", ret);
+
char data[CYASSL_MAX_ERROR_SZ];
char data_new[CYASSL_MAX_ERROR_SZ];
strcpy(data_new, CyaSSL_ERR_error_string(err, data));
@@ -60,7 +69,10 @@
} else {
logError("Failed to get error code [%d], Reason: [%s]\r\n", err, data_new);
}
+
goto fail;
+ } else {
+ break;
}
}
@@ -133,19 +145,71 @@
}
int TlsMQTTClient::read(unsigned char* data, int max, int timeout) {
- return CyaSSL_read(ssl, data, max);
+ //logTrace("TlsMQTTClient::read data %p max %d timeout %d", data, max, timeout);
+ Timer tmr;
+ int bytes = 0;
+ int totalbytes = 0;
+
+ tmr.start();
+ do {
+ bytes = CyaSSL_read(ssl, data, max);
+ if (bytes < 0) {
+ int err = CyaSSL_get_error(ssl, bytes);
+ if (SSL_ERROR_WANT_READ == err) {
+ continue;
+ }
+ logTrace("CyaSSL_read fail %d", err);
+ return -1;
+ }
+ totalbytes += bytes;
+ } while ( tmr.read_ms() < timeout && totalbytes < max);
+ //logTrace("TlsMQTTClient::read totalbytes %d", totalbytes);
+ return totalbytes;
}
int TlsMQTTClient::write(const unsigned char* data, int length, int timeout) {
- return CyaSSL_write(ssl, data, length);
+ //logTrace("TlsMQTTClient::write data %p max %d timeout %d", data, length, timeout);
+ Timer tmr;
+ int bytes = 0;
+ int totalbytes = 0;
+
+ tmr.start();
+ do {
+ bytes = CyaSSL_write(ssl, data, length);
+ if (bytes < 0) {
+ int err = CyaSSL_get_error(ssl, bytes);
+ if (SSL_ERROR_WANT_WRITE == err) {
+ continue;
+ }
+ logTrace("CyaSSL_write fail %d", err);
+ return -1;
+ }
+ totalbytes += bytes;
+ } while (tmr.read_ms() < timeout && totalbytes < length);
+ //logTrace("TlsMQTTClient::write totalbytes %d", totalbytes);
+ return totalbytes;
}
int TlsMQTTClient::ioRecv(CYASSL* ssl, char *buf, int sz, void *ctx) {
TlsMQTTClient* thiz = (TlsMQTTClient*) ctx;
- return thiz->tcp->receive(buf, sz);
+ int n = thiz->tcp->receive(buf, sz);
+ if (0 == n) {
+ return CYASSL_CBIO_ERR_WANT_READ;
+ } else if (n > 0) {
+ return n;
+ } else {
+ return CYASSL_CBIO_ERR_GENERAL;
+ }
}
int TlsMQTTClient::ioSend(CYASSL* ssl, char *buf, int sz, void *ctx) {
TlsMQTTClient* thiz = (TlsMQTTClient*) ctx;
- return thiz->tcp->send(buf, sz);
+ int n = thiz->tcp->send(buf, sz);
+ if (0 == n) {
+ return CYASSL_CBIO_ERR_WANT_WRITE;
+ } else if (n > 0) {
+ return n;
+ } else {
+ return CYASSL_CBIO_ERR_GENERAL;
+ }
}