Skip to content

Commit

Permalink
LTE: Fix problem of getting stuck when sending MQTT
Browse files Browse the repository at this point in the history
Since sending MQTT while the network is lost will get stuck,
a timeout is provided to avoid this problem.
  • Loading branch information
SPRESENSE committed Oct 4, 2022
1 parent 1e7c592 commit db6897d
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ parsePacket KEYWORD2
remoteIP KEYWORD2
remotePort KEYWORD2
setTimeout KEYWORD2
setSendTimeout KEYWORD2
getRAT KEYWORD2

#######################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
#define CONNECTED 1
#define FAILED -1
#define TLS_READ_TIMEOUT 10000
#define TLS_WRITE_TIMEOUT (60*1000)

/****************************************************************************
* Public Functions
Expand All @@ -70,6 +71,7 @@ LTETLSClient::LTETLSClient()
, _tlsContext(NULL)
, _connected(NOT_CONNECTED)
, _timeout(TLS_READ_TIMEOUT)
, _writeTimeout(TLS_WRITE_TIMEOUT)
{
}

Expand Down Expand Up @@ -149,7 +151,7 @@ size_t LTETLSClient::write(const uint8_t *buf, size_t size)
return 0;
}

ret = tlsWrite(_tlsContext, buf, size);
ret = tlsWrite(_tlsContext, buf, size, _writeTimeout);
if (ret < 0) {
stop();
return 0;
Expand Down Expand Up @@ -505,3 +507,10 @@ int LTETLSClient::setTimeout(uint32_t milliseconds)

return 0;
}

int LTETLSClient::setSendTimeout(uint32_t milliseconds)
{
_writeTimeout = milliseconds;

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,19 @@ class LTETLSClient : public Client
*/
int setTimeout(uint32_t milliseconds);

/**
* @brief Set the timeout when the client send.
*
* @details [en] Set the timeout when the client send. 0 means disabled (no timeout). If this method has not been called, the timeout is 60 seconds.
*
* @details [ja] クライアントが送信をする際のタイムアウトを設定します。0は無効(タイムアウトしない)を意味します。本メソッドを呼び出さない場合のタイムアウトは60秒です。
*
* @return [en] Returns 0 if succeeded, -1 if not.
*
* @return [ja] 成功した場合は0を、そうでない場合は-1を返します。
*/
int setSendTimeout(uint32_t milliseconds);

private:
int _peekVal;
char *_rootCA;
Expand All @@ -392,6 +405,7 @@ class LTETLSClient : public Client
tlsClientContext_t *_tlsContext;
uint8_t _connected;
uint32_t _timeout;
uint32_t _writeTimeout;
};

/** @} ltetlsclient */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <string.h>
#include <TLSClient.h>
#include <WString.h>
#include <time.h>

/****************************************************************************
* Pre-processor Definitions
Expand All @@ -44,6 +45,51 @@

static const char *g_pers = "spresense-tls";

/****************************************************************************
* Private Functions
****************************************************************************/

static void startTimer(struct timespec *timer)
{
clock_gettime(CLOCK_MONOTONIC, timer);
}

static uint32_t leftTimer(struct timespec *timer, uint32_t timeout_ms)
{
struct timespec current_time;
struct timespec diff_time;
uint32_t difftime_msec = 0;

clock_gettime(CLOCK_MONOTONIC, &current_time);

diff_time.tv_sec = current_time.tv_sec - timer->tv_sec;
diff_time.tv_nsec = current_time.tv_nsec - timer->tv_nsec;

if (diff_time.tv_nsec < 0) {
diff_time.tv_sec -= 1;
diff_time.tv_nsec += 1000*1000*1000;
}

difftime_msec = diff_time.tv_sec*1000 + diff_time.tv_nsec/(1000*1000);

if (difftime_msec < timeout_ms) {
return timeout_ms - difftime_msec;
}

return 0;
}

static bool hasTimerExpired(struct timespec *timer, uint32_t timeout_ms)
{
if (timeout_ms) {
return leftTimer(timer, timeout_ms) ? false : true;
}

/* 0 means no timeout */

return false;
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down Expand Up @@ -241,15 +287,22 @@ int tlsRead(tlsClientContext_t *tlsCtx, uint8_t *buffer, int len)
return ret;
}

int tlsWrite(tlsClientContext_t *tlsCtx, const uint8_t *buffer, int len)
int tlsWrite(tlsClientContext_t *tlsCtx, const uint8_t *buffer, int len,
uint32_t timeout)
{
int ret;
struct timespec timer;

startTimer(&timer);

while ((ret = mbedtls_ssl_write(&tlsCtx->ssl, buffer, len)) <= 0) {
if ((ret != MBEDTLS_ERR_SSL_WANT_READ) &&
(ret != MBEDTLS_ERR_SSL_WANT_WRITE)) {
TLSCERR("mbedtls_ssl_write() error : -0x%x\n", -ret);
return ret;
} else if (hasTimerExpired(&timer, timeout)) {
TLSCERR("write timer expired : -0x%x\n", -ret);
return ret;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ int tlsConnect(tlsClientContext_t *tlsCtx, const char *host, uint32_t port,
const char *privateKey, size_t privateKeySize);
int tlsGetAvailable(tlsClientContext_t *tlsCtx);
int tlsRead(tlsClientContext_t *tlsCtx, uint8_t *buffer, int len);
int tlsWrite(tlsClientContext_t *tlsCtx, const uint8_t *buffer, int len);
int tlsWrite(tlsClientContext_t *tlsCtx, const uint8_t *buffer, int len,
uint32_t timeout);

#endif

0 comments on commit db6897d

Please sign in to comment.