Пример #1
0
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);
			}
		}
	}
}
Пример #8
0
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;
}