IoT_Error_t iot_tls_write(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *written_len) { size_t written_so_far; bool isErrorFlag = false; int frags, ret = 0; TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams); for(written_so_far = 0, frags = 0; written_so_far < len && !has_timer_expired(timer); written_so_far += ret, frags++) { while(!has_timer_expired(timer) && (ret = mbedtls_ssl_write(&(tlsDataParams->ssl), pMsg + written_so_far, len - written_so_far)) <= 0) { if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { ESP_LOGE(TAG, "failed! mbedtls_ssl_write returned -0x%x", -ret); /* All other negative return values indicate connection needs to be reset. * Will be caught in ping request so ignored here */ isErrorFlag = true; break; } } if(isErrorFlag) { break; } } *written_len = written_so_far; if(isErrorFlag) { return NETWORK_SSL_WRITE_ERROR; } else if(has_timer_expired(timer) && written_so_far != len) { return NETWORK_SSL_WRITE_TIMEOUT_ERROR; } return SUCCESS; }
/* only used in single-threaded mode where one command at a time is in process */ IoT_Error_t aws_iot_mqtt_internal_wait_for_read(AWS_IoT_Client *pClient, uint8_t packetType, Timer *pTimer) { IoT_Error_t rc; uint8_t read_packet_type; FUNC_ENTRY; if(NULL == pClient || NULL == pTimer) { FUNC_EXIT_RC(NULL_VALUE_ERROR); } read_packet_type = 0; do { if(has_timer_expired(pTimer)) { /* we timed out */ rc = MQTT_REQUEST_TIMEOUT_ERROR; break; } rc = aws_iot_mqtt_internal_cycle_read(pClient, pTimer, &read_packet_type); } while(NETWORK_DISCONNECTED_ERROR != rc && read_packet_type != packetType); if(MQTT_REQUEST_TIMEOUT_ERROR != rc && NETWORK_DISCONNECTED_ERROR != rc && read_packet_type != packetType) { FUNC_EXIT_RC(FAILURE); } /* Something failed or we didn't receive the expected packet, return error code */ FUNC_EXIT_RC(rc); }
IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *read_len) { int val = -1; int recv_len = 0; int error_flag = false, complete_flag = false; unsigned int timeout = timer->timeout; wm_tls_reset_read_timer(&tls_hd); wm_tls_set_read_timeout(&tls_hd, timeout); do { val = wm_tls_client_read(&tls_hd, pMsg + recv_len, len - recv_len); if (val >= 0) { recv_len += val; } else { error_flag = true; } if (recv_len >= len) { complete_flag = true; } } while (!error_flag && !complete_flag); *read_len = recv_len; if (0 == *read_len && error_flag) { return NETWORK_SSL_NOTHING_TO_READ; } else if (has_timer_expired(timer) && !complete_flag) { return NETWORK_SSL_READ_TIMEOUT_ERROR; } return AWS_SUCCESS; }
IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *read_len) { mbedtls_ssl_context *ssl = &(pNetwork->tlsDataParams.ssl); size_t rxLen = 0; int ret; while (len > 0) { // This read will timeout after IOT_SSL_READ_TIMEOUT if there's no data to be read ret = mbedtls_ssl_read(ssl, pMsg, len); if (ret > 0) { rxLen += ret; pMsg += ret; len -= ret; } else if (ret == 0 || (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_TIMEOUT)) { return NETWORK_SSL_READ_ERROR; } // Evaluate timeout after the read to make sure read is done at least once if (has_timer_expired(timer)) { break; } } if (len == 0) { *read_len = rxLen; return SUCCESS; } if (rxLen == 0) { return NETWORK_SSL_NOTHING_TO_READ; } else { return NETWORK_SSL_READ_TIMEOUT_ERROR; } }
IoT_Error_t subscribeToShadowActionAcks(const char *pThingName, ShadowActions_t action, bool isSticky) { IoT_Error_t ret_val = SUCCESS; bool clearBothEntriesFromList = true; int16_t indexAcceptedSubList = 0; int16_t indexRejectedSubList = 0; Timer subSettlingtimer; indexAcceptedSubList = getNextFreeIndexOfSubscriptionList(); indexRejectedSubList = getNextFreeIndexOfSubscriptionList(); if(indexAcceptedSubList >= 0 && indexRejectedSubList >= 0) { topicNameFromThingAndAction(SubscriptionList[indexAcceptedSubList].Topic, pThingName, action, SHADOW_ACCEPTED); ret_val = aws_iot_mqtt_subscribe(pMqttClient, SubscriptionList[indexAcceptedSubList].Topic, (uint16_t) strlen(SubscriptionList[indexAcceptedSubList].Topic), QOS0, AckStatusCallback, NULL); if(ret_val == SUCCESS) { SubscriptionList[indexAcceptedSubList].count = 1; SubscriptionList[indexAcceptedSubList].isSticky = isSticky; topicNameFromThingAndAction(SubscriptionList[indexRejectedSubList].Topic, pThingName, action, SHADOW_REJECTED); ret_val = aws_iot_mqtt_subscribe(pMqttClient, SubscriptionList[indexRejectedSubList].Topic, (uint16_t) strlen(SubscriptionList[indexRejectedSubList].Topic), QOS0, AckStatusCallback, NULL); if(ret_val == SUCCESS) { SubscriptionList[indexRejectedSubList].count = 1; SubscriptionList[indexRejectedSubList].isSticky = isSticky; clearBothEntriesFromList = false; // wait for SUBSCRIBE_SETTLING_TIME seconds to let the subscription take effect init_timer(&subSettlingtimer); countdown_sec(&subSettlingtimer, SUBSCRIBE_SETTLING_TIME); while(!has_timer_expired(&subSettlingtimer)); } } } if(clearBothEntriesFromList) { if(indexAcceptedSubList >= 0) { SubscriptionList[indexAcceptedSubList].isFree = true; } else if(indexRejectedSubList >= 0) { SubscriptionList[indexRejectedSubList].isFree = true; } if(SubscriptionList[indexAcceptedSubList].count == 1) { aws_iot_mqtt_unsubscribe(pMqttClient, SubscriptionList[indexAcceptedSubList].Topic, (uint16_t) strlen(SubscriptionList[indexAcceptedSubList].Topic)); } } return ret_val; }
IoT_Error_t aws_iot_mqtt_internal_send_packet(AWS_IoT_Client *pClient, size_t length, Timer *pTimer) { size_t sentLen, sent; IoT_Error_t rc; FUNC_ENTRY; if(NULL == pClient || NULL == pTimer) { FUNC_EXIT_RC(NULL_VALUE_ERROR); } if(length >= pClient->clientData.writeBufSize) { FUNC_EXIT_RC(MQTT_TX_BUFFER_TOO_SHORT_ERROR); } #ifdef _ENABLE_THREAD_SUPPORT_ rc = aws_iot_mqtt_client_lock_mutex(pClient, &(pClient->clientData.tls_write_mutex)); if(SUCCESS != rc) { FUNC_EXIT_RC(rc); } #endif sentLen = 0; sent = 0; while(sent < length && !has_timer_expired(pTimer)) { rc = pClient->networkStack.write(&(pClient->networkStack), &pClient->clientData.writeBuf[sent], length, pTimer, &sentLen); if(SUCCESS != rc) { /* there was an error writing the data */ break; } sent += sentLen; } #ifdef _ENABLE_THREAD_SUPPORT_ rc = aws_iot_mqtt_client_unlock_mutex(pClient, &(pClient->clientData.tls_write_mutex)); if(SUCCESS != rc) { FUNC_EXIT_RC(rc); } #endif if(sent == length) { /* record the fact that we have successfully sent the packet */ //countdown_sec(&c->pingTimer, c->clientData.keepAliveInterval); FUNC_EXIT_RC(SUCCESS); } FUNC_EXIT_RC(FAILURE); }
void HandleExpiredResponseCallbacks(void) { uint8_t i; for(i = 0; i < MAX_ACKS_TO_COMEIN_AT_ANY_GIVEN_TIME; i++) { if(!AckWaitList[i].isFree) { if(has_timer_expired(&(AckWaitList[i].timer))) { if(AckWaitList[i].callback != NULL) { AckWaitList[i].callback(AckWaitList[i].thingName, AckWaitList[i].action, SHADOW_ACK_TIMEOUT, shadowRxBuf, AckWaitList[i].pCallbackContext); } AckWaitList[i].isFree = true; unsubscribeFromAcceptedAndRejected(i); } } } }
IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *read_len) { TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams); mbedtls_ssl_context *ssl = &(tlsDataParams->ssl); mbedtls_ssl_config *ssl_conf = &(tlsDataParams->conf); uint32_t read_timeout; size_t rxLen = 0; int ret; read_timeout = ssl_conf->read_timeout; while (len > 0) { /* Make sure we never block on read for longer than timer has left, but also that we don't block indefinitely (ie read_timeout > 0) */ mbedtls_ssl_conf_read_timeout(ssl_conf, MAX(1, MIN(read_timeout, left_ms(timer)))); ret = mbedtls_ssl_read(ssl, pMsg, len); /* Restore the old timeout */ mbedtls_ssl_conf_read_timeout(ssl_conf, read_timeout); if (ret > 0) { rxLen += ret; pMsg += ret; len -= ret; } else if (ret == 0 || (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_TIMEOUT)) { return NETWORK_SSL_READ_ERROR; } // Evaluate timeout after the read to make sure read is done at least once if (has_timer_expired(timer)) { break; } } if (len == 0) { *read_len = rxLen; return SUCCESS; } if (rxLen == 0) { return NETWORK_SSL_NOTHING_TO_READ; } else { return NETWORK_SSL_READ_TIMEOUT_ERROR; } }
IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *read_len) { int val = -1; int recv_len = 0; fd_set fds; int time_left, error_flag = false, complete_flag = false; FD_ZERO(&fds); FD_SET(pNetwork->my_socket, &fds); setsockopt(pNetwork->my_socket, SOL_SOCKET, SO_RCVTIMEO, (void *)&pNetwork->tlsConnectParams.timeout_ms, sizeof(pNetwork->tlsConnectParams.timeout_ms)); do { if (tls_handle) { val = tls_recv(tls_handle, pMsg + recv_len, len - recv_len); } if (val >= 0) { recv_len += val; } else { error_flag = true; } if (recv_len >= len) { complete_flag = true; } time_left = left_ms(timer); } while (!error_flag && !complete_flag && time_left > 0); *read_len = recv_len; if (0 == *read_len && error_flag) { return NETWORK_SSL_NOTHING_TO_READ; } else if (has_timer_expired(timer) && !complete_flag) { return NETWORK_SSL_READ_TIMEOUT_ERROR; } return AWS_SUCCESS; }
IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *read_len) { size_t rxLen = 0; bool isErrorFlag = false; bool isCompleteFlag = false; uint32_t timerLeftVal = left_ms(timer); TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams); int ret = 0; do { //mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), timerLeftVal); ret = mbedtls_ssl_read(&(tlsDataParams->ssl), pMsg, len); if (ret >= 0) { /* 0 is for EOF */ rxLen += ret; } else if (ret != MBEDTLS_ERR_SSL_WANT_READ) { isErrorFlag = true; } /* All other negative return values indicate connection needs to be reset. * Will be caught in ping request so ignored here */ if (rxLen >= len) { isCompleteFlag = true; } timerLeftVal = left_ms(timer); } while(!isErrorFlag && !isCompleteFlag && timerLeftVal > 0); *read_len = rxLen; if(0 == rxLen && isErrorFlag) { return NETWORK_SSL_NOTHING_TO_READ; } else if(has_timer_expired(timer) && !isCompleteFlag) { return NETWORK_SSL_READ_TIMEOUT_ERROR; } return SUCCESS; }