/* G:6 - Yield, network disconnected, ping timeout, auto-reconnect disabled */ TEST_C(YieldTests, disconnectNoAutoReconnect) { IoT_Error_t rc = FAILURE; IOT_DEBUG("-->Running Yield Tests - G:6 - Yield, network disconnected, ping timeout, auto-reconnect disabled \n"); rc = aws_iot_mqtt_autoreconnect_set_status(&iotClient, true); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(true, aws_iot_is_autoreconnect_enabled(&iotClient)); /* Disable Autoreconnect, then let ping request time out and call yield */ aws_iot_mqtt_autoreconnect_set_status(&iotClient, false); sleep((uint16_t)(iotClient.clientData.keepAliveInterval / 2)); ResetTLSBuffer(); /* Sleep for half keep alive interval to allow the first ping to be sent out */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, isLastTLSTxMessagePingreq()); /* Let ping request time out and call yield */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2 + 1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(NETWORK_DISCONNECTED_ERROR, rc); CHECK_EQUAL_C_INT(1, isLastTLSTxMessageDisconnect()); CHECK_EQUAL_C_INT(0, aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(true, dcHandlerInvoked); IOT_DEBUG("-->Success - G:6 - Yield, network disconnected, ping timeout, auto-reconnect disabled \n"); }
void parseInputArgsForConnectParams(int argc, char** argv) { int opt; while (-1 != (opt = getopt(argc, argv, "h:p:c:"))) { switch (opt) { case 'h': strcpy(HostAddress, optarg); IOT_DEBUG("Host %s", optarg); break; case 'p': port = atoi(optarg); IOT_DEBUG("arg %s", optarg); break; case 'c': strcpy(certDirectory, optarg); IOT_DEBUG("cert root directory %s", optarg); break; case '?': if (optopt == 'c') { IOT_ERROR("Option -%c requires an argument.", optopt); } else if (isprint(optopt)) { IOT_WARN("Unknown option `-%c'.", optopt); } else { IOT_WARN("Unknown option character `\\x%x'.", optopt); } break; default: IOT_ERROR("ERROR in command line argument parsing"); break; } } }
/* G:9 - Yield, disconnected, Auto-reconnect timed-out */ TEST_C(YieldTests, disconnectAutoReconnectTimeout) { IoT_Error_t rc = FAILURE; IOT_DEBUG("-->Running Yield Tests - G:9 - Yield, disconnected, Auto-reconnect timed-out \n"); rc = aws_iot_mqtt_autoreconnect_set_status(&iotClient, true); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(true, aws_iot_is_autoreconnect_enabled(&iotClient)); ResetTLSBuffer(); /* Sleep for half keep alive interval to allow the first ping to be sent out */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, isLastTLSTxMessagePingreq()); /* Let ping request time out and call yield */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2 + 1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(NETWORK_ATTEMPTING_RECONNECT, rc); CHECK_EQUAL_C_INT(0, aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(true, dcHandlerInvoked); IOT_DEBUG("-->Success - G:9 - Yield, disconnected, Auto-reconnect timed-out \n"); }
/* G:8 - Yield, network connected, ping request/response */ TEST_C(YieldTests, PingRequestPingResponse) { IoT_Error_t rc = SUCCESS; int i = 0; int j = 0; int attempt = 3; IOT_DEBUG("-->Running Yield Tests - G:8 - Yield, network connected, ping request/response \n"); IOT_DEBUG("Current Keep Alive Interval is set to %d sec.\n", iotClient.clientData.keepAliveInterval); for(i = 0; i < attempt; i++) { IOT_DEBUG("[Round_%d/Total_%d] Waiting for %d sec...\n", i + 1, attempt, iotClient.clientData.keepAliveInterval); /* Set TLS buffer for ping response */ ResetTLSBuffer(); setTLSRxBufferForPingresp(); for(j = 0; j <= iotClient.clientData.keepAliveInterval; j++) { sleep(1); IOT_DEBUG("[Waited %d secs]", j + 1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); } /* Check whether ping was processed correctly and new Ping request was generated */ CHECK_EQUAL_C_INT(1, isLastTLSTxMessagePingreq()); } IOT_DEBUG("-->Success - G:8 - Yield, network connected, ping request/response \n"); }
static int _iot_tls_verify_cert(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) { char buf[1024]; ((void) data); IOT_DEBUG("\nVerify requested for (Depth %d):\n", depth); mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt); IOT_DEBUG("%s", buf); if((*flags) == 0) { IOT_DEBUG(" This certificate has no flags\n"); } else { IOT_DEBUG(buf, sizeof(buf), " ! ", *flags); IOT_DEBUG("%s\n", buf); } return 0; }
/* F:4 - Disconnect attempt, not connected */ TEST_C(DisconnectTests, disconnectNotConnected) { IoT_Error_t rc = SUCCESS; IOT_DEBUG("-->Running Disconnect Tests - F:4 - Disconnect attempt, not connected \n"); /* First make sure client is disconnected */ rc = aws_iot_mqtt_disconnect(&iotClient); /* Check client is disconnected */ CHECK_EQUAL_C_INT(false, aws_iot_mqtt_is_client_connected(&iotClient)); /* Now call disconnect again */ rc = aws_iot_mqtt_disconnect(&iotClient); CHECK_EQUAL_C_INT(NETWORK_DISCONNECTED_ERROR, rc); IOT_DEBUG("-->Success - F:4 - Disconnect attempt, not connected \n"); }
void DeltaCallback(const char *pJsonValueBuffer, uint32_t valueLength, jsonStruct_t *pJsonStruct_t) { IOT_UNUSED(pJsonStruct_t); IOT_DEBUG("Received Delta message %.*s", valueLength, pJsonValueBuffer); if (buildJSONForReported(stringToEchoDelta, SHADOW_MAX_SIZE_OF_RX_BUFFER, pJsonValueBuffer, valueLength)) { messageArrivedOnDelta = true; } }
/* G:5 - Yield, network connected, yield called while in subscribe application callback */ TEST_C(YieldTests, YieldInSubscribeCallback) { IoT_Error_t rc = SUCCESS; char expectedCallbackString[] = "0xA5A5A3"; IOT_DEBUG("-->Running Yield Tests - G:5 - Yield, network connected, yield called while in subscribe application callback \n"); setTLSRxBufferForSuback(subTopic, subTopicLen, QOS1, testPubMsgParams); rc = aws_iot_mqtt_subscribe(&iotClient, subTopic, subTopicLen, QOS1, iot_tests_unit_yield_test_subscribe_callback_handler, NULL); if(SUCCESS == rc) { setTLSRxBufferWithMsgOnSubscribedTopic(subTopic, subTopicLen, QOS1, testPubMsgParams, expectedCallbackString); rc = aws_iot_mqtt_yield(&iotClient, 1000); if(SUCCESS == rc) { CHECK_EQUAL_C_STRING(expectedCallbackString, CallbackMsgString); } CHECK_EQUAL_C_INT(1, isLastTLSTxMessagePuback()); } IOT_DEBUG("-->Success - G:5 - Yield, network connected, yield called while in subscribe application callback \n"); }
/* G:11 - Yield, disconnected, Manual reconnect */ TEST_C(YieldTests, disconnectManualAutoReconnect) { IoT_Error_t rc = FAILURE; unsigned char *currPayload = NULL; IOT_DEBUG("-->Running Yield Tests - G:11 - Yield, disconnected, Manual reconnect \n"); CHECK_C(aws_iot_mqtt_is_client_connected(&iotClient)); /* Disable Autoreconnect, then let ping request time out and call yield */ aws_iot_mqtt_autoreconnect_set_status(&iotClient, false); CHECK_C(!aws_iot_is_autoreconnect_enabled(&iotClient)); /* Sleep for half keep alive interval to allow the first ping to be sent out */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, isLastTLSTxMessagePingreq()); /* Let ping request time out and call yield */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2 + 1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(NETWORK_DISCONNECTED_ERROR, rc); CHECK_EQUAL_C_INT(1, isLastTLSTxMessageDisconnect()); CHECK_C(!aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(true, dcHandlerInvoked); dcHandlerInvoked = false; setTLSRxBufferForConnack(&connectParams, 0, 0); rc = aws_iot_mqtt_attempt_reconnect(&iotClient); CHECK_EQUAL_C_INT(NETWORK_RECONNECTED, rc); currPayload = connectTxBufferHeaderParser(&prfrdParams, TxBuffer.pBuffer); CHECK_C(true == isConnectTxBufFlagCorrect(&connectParams, &prfrdParams)); CHECK_C(true == isConnectTxBufPayloadCorrect(&connectParams, currPayload)); CHECK_C(aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(false, dcHandlerInvoked); IOT_DEBUG("-->Success - G:11 - Yield, disconnected, Manual reconnect \n"); }
/* G:10 - Yield, disconnected, Auto-reconnect successful */ TEST_C(YieldTests, disconnectAutoReconnectSuccess) { IoT_Error_t rc = FAILURE; unsigned char *currPayload = NULL; IOT_DEBUG("-->Running Yield Tests - G:10 - Yield, disconnected, Auto-reconnect successful \n"); rc = aws_iot_mqtt_autoreconnect_set_status(&iotClient, true); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(true, aws_iot_is_autoreconnect_enabled(&iotClient)); /* Sleep for half keep alive interval to allow the first ping to be sent out */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, isLastTLSTxMessagePingreq()); /* Let ping request time out and call yield */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2 + 1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(NETWORK_ATTEMPTING_RECONNECT, rc); sleep(2); /* Default min reconnect delay is 1 sec */ printf("\nWakeup"); setTLSRxBufferForConnack(&connectParams, 0, 0); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); currPayload = connectTxBufferHeaderParser(&prfrdParams, TxBuffer.pBuffer); CHECK_C(true == isConnectTxBufFlagCorrect(&connectParams, &prfrdParams)); CHECK_C(true == isConnectTxBufPayloadCorrect(&connectParams, currPayload)); CHECK_EQUAL_C_INT(true, aws_iot_mqtt_is_client_connected(&iotClient)); CHECK_EQUAL_C_INT(true, dcHandlerInvoked); IOT_DEBUG("-->Success - G:10 - Yield, disconnected, Auto-reconnect successful \n"); }
/* G:7 - Yield, network connected, no incoming messages */ TEST_C(YieldTests, YieldSuccessNoMessages) { IoT_Error_t rc; int i; IOT_DEBUG("-->Running Yield Tests - G:7 - Yield, network connected, no incoming messages \n"); for(i = 0; i < 100; i++) { CallbackMsgString[i] = 'x'; } rc = aws_iot_mqtt_yield(&iotClient, 1000); if(SUCCESS == rc) { /* Check no messages were received */ for(i = 0; i < 100; i++) { if('x' != CallbackMsgString[i]) { rc = FAILURE; } } } CHECK_EQUAL_C_INT(SUCCESS, rc); IOT_DEBUG("-->Success - G:7 - Yield, network connected, no incoming messages \n"); }
void parseInputArgsForConnectParams(int argc, char **argv) { int opt; while (-1 != (opt = getopt(argc, argv, "h:p:c:t:s:"))) { switch (opt) { case 'h': strcpy(HostAddress, optarg); IOT_DEBUG("host %s\n", optarg); break; case 'p': port = atoi(optarg); IOT_DEBUG("port %s\n", optarg); break; case 'c': strcpy(certDirectory, optarg); IOT_DEBUG("cert root directory %s\n", optarg); break; case 't': strcpy(publishTopicName, optarg); IOT_DEBUG("publish topic name: %s\n", optarg); break; case 'f': strcpy(filename, optarg); IOT_DEBUG("config file %s", optarg); break; case 's': strcpy(subscribeTopicName, optarg); IOT_DEBUG("subscribe topic name: %s\n", optarg); break; case '?': if (optopt == 'c') { IOT_ERROR("Option -%c requires an argument.", optopt); } else if (isprint(optopt)) { IOT_WARN("Unknown option `-%c'.", optopt); } else { IOT_WARN("Unknown option character `\\x%x'.", optopt); } break; default: IOT_ERROR("Error in command line argument parsing"); break; } } }
IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { int ret = 0; const char *pers = "aws_iot_tls_wrapper"; TLSDataParams *tlsDataParams = NULL; char portBuffer[6]; char vrfy_buf[512]; #ifdef IOT_DEBUG unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1]; #endif if(NULL == pNetwork) { return NULL_VALUE_ERROR; } if(NULL != params) { _iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation, params->pDevicePrivateKeyLocation, params->pDestinationURL, params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag); } tlsDataParams = &(pNetwork->tlsDataParams); mbedtls_net_init(&(tlsDataParams->server_fd)); mbedtls_ssl_init(&(tlsDataParams->ssl)); mbedtls_ssl_config_init(&(tlsDataParams->conf)); mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg)); mbedtls_x509_crt_init(&(tlsDataParams->cacert)); mbedtls_x509_crt_init(&(tlsDataParams->clicert)); mbedtls_pk_init(&(tlsDataParams->pkey)); IOT_DEBUG("\n . Seeding the random number generator..."); mbedtls_entropy_init(&(tlsDataParams->entropy)); if((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy), (const unsigned char *) pers, strlen(pers))) != 0) { IOT_ERROR(" failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret); return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED; } IOT_DEBUG(" . Loading the CA root certificate ..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->cacert), pNetwork->tlsConnectParams.pRootCALocation); if(ret < 0) { IOT_ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing root cert\n\n", -ret); return NETWORK_X509_ROOT_CRT_PARSE_ERROR; } IOT_DEBUG(" ok (%d skipped)\n", ret); IOT_DEBUG(" . Loading the client cert. and key..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->clicert), pNetwork->tlsConnectParams.pDeviceCertLocation); if(ret != 0) { IOT_ERROR(" failed\n ! mbedtls_x509_crt_parse returned -0x%x while parsing device cert\n\n", -ret); return NETWORK_X509_DEVICE_CRT_PARSE_ERROR; } ret = mbedtls_pk_parse_keyfile(&(tlsDataParams->pkey), pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, ""); if(ret != 0) { IOT_ERROR(" failed\n ! mbedtls_pk_parse_key returned -0x%x while parsing private key\n\n", -ret); IOT_DEBUG(" path : %s ", pNetwork->tlsConnectParams.pDevicePrivateKeyLocation); return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR; } IOT_DEBUG(" ok\n"); snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort); IOT_DEBUG(" . Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer); if((ret = mbedtls_net_connect(&(tlsDataParams->server_fd), pNetwork->tlsConnectParams.pDestinationURL, portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) { IOT_ERROR(" failed\n ! mbedtls_net_connect returned -0x%x\n\n", -ret); switch(ret) { case MBEDTLS_ERR_NET_SOCKET_FAILED: return NETWORK_ERR_NET_SOCKET_FAILED; case MBEDTLS_ERR_NET_UNKNOWN_HOST: return NETWORK_ERR_NET_UNKNOWN_HOST; case MBEDTLS_ERR_NET_CONNECT_FAILED: default: return NETWORK_ERR_NET_CONNECT_FAILED; }; } ret = mbedtls_net_set_block(&(tlsDataParams->server_fd)); if(ret != 0) { IOT_ERROR(" failed\n ! net_set_(non)block() returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } IOT_DEBUG(" ok\n"); IOT_DEBUG(" . Setting up the SSL/TLS structure..."); if((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { IOT_ERROR(" failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL); } mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg)); mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL); if((ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey))) != 0) { IOT_ERROR(" failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret); return SSL_CONNECTION_ERROR; } mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms); if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) { IOT_ERROR(" failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret); return SSL_CONNECTION_ERROR; } if((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), pNetwork->tlsConnectParams.pDestinationURL)) != 0) { IOT_ERROR(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret); return SSL_CONNECTION_ERROR; } IOT_DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); mbedtls_ssl_set_bio(&(tlsDataParams->ssl), &(tlsDataParams->server_fd), mbedtls_net_send, NULL, mbedtls_net_recv_timeout); IOT_DEBUG(" ok\n"); IOT_DEBUG("\n\nSSL state connect : %d ", tlsDataParams->ssl.state); IOT_DEBUG(" . Performing the SSL/TLS handshake..."); while((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0) { if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { IOT_ERROR(" failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret); if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { IOT_ERROR(" Unable to verify the server's certificate. " "Either it is invalid,\n" " or you didn't set ca_file or ca_path " "to an appropriate value.\n" " Alternatively, you may want to use " "auth_mode=optional for testing purposes.\n"); } return SSL_CONNECTION_ERROR; } } IOT_DEBUG(" ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&(tlsDataParams->ssl)), mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl))); if((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0) { IOT_DEBUG(" [ Record expansion is %d ]\n", ret); } else { IOT_DEBUG(" [ Record expansion is unknown (compression) ]\n"); } IOT_DEBUG(" . Verifying peer X.509 certificate..."); if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) { if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0) { IOT_ERROR(" failed\n"); mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), " ! ", tlsDataParams->flags); IOT_ERROR("%s\n", vrfy_buf); ret = SSL_CONNECTION_ERROR; } else { IOT_DEBUG(" ok\n"); ret = SUCCESS; } } else { IOT_DEBUG(" Server Verification skipped\n"); ret = SUCCESS; } #ifdef IOT_DEBUG if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL) { IOT_DEBUG(" . Peer certificate information ...\n"); mbedtls_x509_crt_info((char *) buf, sizeof(buf) - 1, " ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl))); IOT_DEBUG("%s\n", buf); } #endif mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), IOT_SSL_READ_TIMEOUT); return (IoT_Error_t) ret; }
int main(int argc, char** argv) { IoT_Error_t rc = SUCCESS; int32_t i = 0; char rootCA[PATH_MAX + 1]; char clientCRT[PATH_MAX + 1]; char clientKey[PATH_MAX + 1]; char CurrentWD[PATH_MAX + 1]; IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); getcwd(CurrentWD, sizeof(CurrentWD)); snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME); snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME); snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME); IOT_DEBUG("rootCA %s", rootCA); IOT_DEBUG("clientCRT %s", clientCRT); IOT_DEBUG("clientKey %s", clientKey); parseInputArgsForConnectParams(argc, argv); // initialize the mqtt client AWS_IoT_Client mqttClient; ShadowInitParameters_t sp = ShadowInitParametersDefault; sp.pHost = AWS_IOT_MQTT_HOST; sp.port = AWS_IOT_MQTT_PORT; sp.pClientCRT = clientCRT; sp.pClientKey = clientKey; sp.pRootCA = rootCA; sp.enableAutoReconnect = false; sp.disconnectHandler = NULL; IOT_INFO("Shadow Init"); rc = aws_iot_shadow_init(&mqttClient, &sp); if (SUCCESS != rc) { IOT_ERROR("Shadow Connection Error"); return rc; } ShadowConnectParameters_t scp = ShadowConnectParametersDefault; scp.pMyThingName = AWS_IOT_MY_THING_NAME; scp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID; scp.mqttClientIdLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID); IOT_INFO("Shadow Connect"); rc = aws_iot_shadow_connect(&mqttClient, &scp); if (SUCCESS != rc) { IOT_ERROR("Shadow Connection Error"); return rc; } /* * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h * #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL * #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL */ rc = aws_iot_shadow_set_autoreconnect_status(&mqttClient, true); if(SUCCESS != rc){ IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); return rc; } jsonStruct_t deltaObject; deltaObject.pData = stringToEchoDelta; deltaObject.pKey = "state"; deltaObject.type = SHADOW_JSON_OBJECT; deltaObject.cb = DeltaCallback; /* * Register the jsonStruct object */ rc = aws_iot_shadow_register_delta(&mqttClient, &deltaObject); // Now wait in the loop to receive any message sent from the console while (NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) { /* * Lets check for the incoming messages for 200 ms. */ rc = aws_iot_shadow_yield(&mqttClient, 200); if (NETWORK_ATTEMPTING_RECONNECT == rc) { sleep(1); // If the client is attempting to reconnect we will skip the rest of the loop. continue; } if (messageArrivedOnDelta) { IOT_INFO("\nSending delta message back %s\n", stringToEchoDelta); rc = aws_iot_shadow_update(&mqttClient, AWS_IOT_MY_THING_NAME, stringToEchoDelta, UpdateStatusCallback, NULL, 2, true); messageArrivedOnDelta = false; } // sleep for some time in seconds sleep(1); } if (SUCCESS != rc) { IOT_ERROR("An error occurred in the loop %d", rc); } IOT_INFO("Disconnecting"); rc = aws_iot_shadow_disconnect(&mqttClient); if (SUCCESS != rc) { IOT_ERROR("Disconnect error %d", rc); } return rc; }
/* G:12 - Yield, resubscribe to all topics on reconnect */ TEST_C(YieldTests, resubscribeSuccessfulReconnect) { IoT_Error_t rc = FAILURE; char cPayload[100]; bool connected = false; bool autoReconnectEnabled = false; char expectedCallbackString[100]; IOT_DEBUG("-->Running Yield Tests - G:12 - Yield, resubscribe to all topics on reconnect \n"); rc = aws_iot_mqtt_autoreconnect_set_status(&iotClient, true); CHECK_EQUAL_C_INT(SUCCESS, rc); snprintf(CallbackMsgString, 100, "NOT_VISITED"); testPubMsgParams.qos = QOS1; testPubMsgParams.isRetained = 0; snprintf(cPayload, 100, "%s : %d ", "hello from SDK", 0); testPubMsgParams.payload = (void *) cPayload; testPubMsgParams.payloadLen = strlen(cPayload); connected = aws_iot_mqtt_is_client_connected(&iotClient); CHECK_EQUAL_C_INT(1, connected); ResetTLSBuffer(); /* Subscribe to a topic */ setTLSRxBufferForSuback(subTopic, subTopicLen, QOS1, testPubMsgParams); rc = aws_iot_mqtt_subscribe(&iotClient, subTopic, subTopicLen, QOS0, iot_tests_unit_acr_subscribe_callback_handler, NULL); CHECK_EQUAL_C_INT(SUCCESS, rc); ResetTLSBuffer(); /* Check subscribe */ snprintf(expectedCallbackString, 100, "Message for %s", subTopic); setTLSRxBufferWithMsgOnSubscribedTopic(subTopic, subTopicLen, QOS1, testPubMsgParams, expectedCallbackString); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_STRING(expectedCallbackString, CallbackMsgString); ResetTLSBuffer(); autoReconnectEnabled = aws_iot_is_autoreconnect_enabled(&iotClient); CHECK_EQUAL_C_INT(1, autoReconnectEnabled); /* Sleep for half keep alive interval to allow the first ping to be sent out */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_INT(true, isLastTLSTxMessagePingreq()); /* Let ping request time out and call yield */ sleep(iotClient.clientData.keepAliveInterval / (uint32_t)2 + 1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(NETWORK_ATTEMPTING_RECONNECT, rc); sleep(2); /* Default min reconnect delay is 1 sec */ ResetTLSBuffer(); setTLSRxBufferForConnackAndSuback(&connectParams, 0, subTopic, subTopicLen, QOS1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); /* Test if reconnect worked */ connected = aws_iot_mqtt_is_client_connected(&iotClient); CHECK_EQUAL_C_INT(true, connected); ResetTLSBuffer(); /* Check subscribe */ snprintf(expectedCallbackString, 100, "Message for %s after resub", subTopic); setTLSRxBufferWithMsgOnSubscribedTopic(subTopic, subTopicLen, QOS1, testPubMsgParams, expectedCallbackString); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); CHECK_EQUAL_C_STRING(expectedCallbackString, CallbackMsgString); CHECK_EQUAL_C_INT(true, dcHandlerInvoked); IOT_DEBUG("-->Success - G:12 - Yield, resubscribe to all topics on reconnect \n"); }
/* F:7 - Disconnect, with set handler and invoked on disconnect */ TEST_C(DisconnectTests, SetHandlerAndInvokedOnDisconnect) { bool connected = false; bool currentAutoReconnectStatus = false; int i; int j; int attempt = 3; uint32_t dcCount = 0; IoT_Error_t rc = SUCCESS; IOT_DEBUG("-->Running Disconnect Tests - F:7 - Disconnect, with set handler and invoked on disconnect \n"); handlerInvoked = false; InitMQTTParamsSetup(&initParams, "localhost", AWS_IOT_MQTT_PORT, false, NULL); rc = aws_iot_mqtt_init(&iotClient, &initParams); CHECK_EQUAL_C_INT(SUCCESS, rc); ConnectMQTTParamsSetup(&connectParams, AWS_IOT_MQTT_CLIENT_ID, (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID)); connectParams.keepAliveIntervalInSec = 5; setTLSRxBufferForConnack(&connectParams, 0, 0); rc = aws_iot_mqtt_connect(&iotClient, &connectParams); CHECK_EQUAL_C_INT(SUCCESS, rc); aws_iot_mqtt_set_disconnect_handler(&iotClient, disconnectTestHandler, NULL); aws_iot_mqtt_autoreconnect_set_status(&iotClient, true); IOT_DEBUG("Current Keep Alive Interval is set to %d sec.\n", connectParams.keepAliveIntervalInSec); currentAutoReconnectStatus = aws_iot_is_autoreconnect_enabled(&iotClient); connected = aws_iot_mqtt_is_client_connected(&iotClient); CHECK_EQUAL_C_INT(1, connected); aws_iot_mqtt_autoreconnect_set_status(&iotClient, false); // 3 cycles of keep alive time expiring // verify a ping request is sent and give a ping response for(i = 0; i < attempt; i++) { /* Set TLS buffer for ping response */ ResetTLSBuffer(); setTLSRxBufferForPingresp(); for(j = 0; j <= connectParams.keepAliveIntervalInSec; j++) { sleep(1); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(SUCCESS, rc); } CHECK_EQUAL_C_INT(1, isLastTLSTxMessagePingreq()); } ResetTLSBuffer(); // keepalive() waits for 1/2 of keepalive time after sending ping request // to receive a pingresponse before determining the connection is not alive // wait for keepalive time and then yield() sleep(connectParams.keepAliveIntervalInSec); rc = aws_iot_mqtt_yield(&iotClient, 100); CHECK_EQUAL_C_INT(NETWORK_DISCONNECTED_ERROR, rc); CHECK_EQUAL_C_INT(1, isLastTLSTxMessageDisconnect()); connected = aws_iot_mqtt_is_client_connected(&iotClient); CHECK_EQUAL_C_INT(0, connected); CHECK_EQUAL_C_INT(true, handlerInvoked); dcCount = aws_iot_mqtt_get_network_disconnected_count(&iotClient); CHECK_C(1 == dcCount); aws_iot_mqtt_reset_network_disconnected_count(&iotClient); dcCount = aws_iot_mqtt_get_network_disconnected_count(&iotClient); CHECK_C(0 == dcCount); ResetTLSBuffer(); aws_iot_mqtt_autoreconnect_set_status(&iotClient, currentAutoReconnectStatus); IOT_DEBUG("-->Success - F:7 - Disconnect, with set handler and invoked on disconnect \n"); }
int main(int argc, char **argv) { IoT_Error_t rc = FAILURE; int32_t i = 0; char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER]; size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]); char *pJsonStringToUpdate; float temperature = 0.0; bool windowOpen = false; jsonStruct_t windowActuator; windowActuator.cb = windowActuate_Callback; windowActuator.pData = &windowOpen; windowActuator.dataLength = sizeof(bool); windowActuator.pKey = "windowOpen"; windowActuator.type = SHADOW_JSON_BOOL; jsonStruct_t temperatureHandler; temperatureHandler.cb = NULL; temperatureHandler.pKey = "temperature"; temperatureHandler.pData = &temperature; temperatureHandler.dataLength = sizeof(float); temperatureHandler.type = SHADOW_JSON_FLOAT; char rootCA[PATH_MAX + 1]; char clientCRT[PATH_MAX + 1]; char clientKey[PATH_MAX + 1]; char CurrentWD[PATH_MAX + 1]; IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); getcwd(CurrentWD, sizeof(CurrentWD)); snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME); snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME); snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME); IOT_DEBUG("rootCA %s", rootCA); IOT_DEBUG("clientCRT %s", clientCRT); IOT_DEBUG("clientKey %s", clientKey); parseInputArgsForConnectParams(argc, argv); // initialize the mqtt client AWS_IoT_Client mqttClient; ShadowInitParameters_t sp = ShadowInitParametersDefault; sp.pHost = AWS_IOT_MQTT_HOST; sp.port = AWS_IOT_MQTT_PORT; sp.pClientCRT = clientCRT; sp.pClientKey = clientKey; sp.pRootCA = rootCA; sp.enableAutoReconnect = false; sp.disconnectHandler = NULL; IOT_INFO("Shadow Init"); rc = aws_iot_shadow_init(&mqttClient, &sp); if(SUCCESS != rc) { IOT_ERROR("Shadow Connection Error"); return rc; } ShadowConnectParameters_t scp = ShadowConnectParametersDefault; scp.pMyThingName = AWS_IOT_MY_THING_NAME; scp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID; scp.mqttClientIdLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID); IOT_INFO("Shadow Connect"); rc = aws_iot_shadow_connect(&mqttClient, &scp); if(SUCCESS != rc) { IOT_ERROR("Shadow Connection Error"); return rc; } /* * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h * #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL * #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL */ rc = aws_iot_shadow_set_autoreconnect_status(&mqttClient, true); if(SUCCESS != rc) { IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); return rc; } rc = aws_iot_shadow_register_delta(&mqttClient, &windowActuator); if(SUCCESS != rc) { IOT_ERROR("Shadow Register Delta Error"); } temperature = STARTING_ROOMTEMPERATURE; // loop and publish a change in temperature while(NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) { rc = aws_iot_shadow_yield(&mqttClient, 200); if(NETWORK_ATTEMPTING_RECONNECT == rc) { sleep(1); // If the client is attempting to reconnect we will skip the rest of the loop. continue; } IOT_INFO("\n=======================================================================================\n"); IOT_INFO("On Device: window state %s", windowOpen ? "true" : "false"); simulateRoomTemperature(&temperature); rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer); if(SUCCESS == rc) { rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 2, &temperatureHandler, &windowActuator); if(SUCCESS == rc) { rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer); if(SUCCESS == rc) { IOT_INFO("Update Shadow: %s", JsonDocumentBuffer); rc = aws_iot_shadow_update(&mqttClient, AWS_IOT_MY_THING_NAME, JsonDocumentBuffer, ShadowUpdateStatusCallback, NULL, 4, true); } } } IOT_INFO("*****************************************************************************************\n"); sleep(1); } if(SUCCESS != rc) { IOT_ERROR("An error occurred in the loop %d", rc); } IOT_INFO("Disconnecting"); rc = aws_iot_shadow_disconnect(&mqttClient); if(SUCCESS != rc) { IOT_ERROR("Disconnect error %d", rc); } return rc; }
int main(int argc, char **argv) { bool infinitePublishFlag = true; char rootCA[PATH_MAX + 1]; char clientCRT[PATH_MAX + 1]; char clientKey[PATH_MAX + 1]; char CurrentWD[PATH_MAX + 1]; char cPayload[100]; int32_t i = 0; IoT_Error_t rc = FAILURE; AWS_IoT_Client client; IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault; IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault; IoT_Publish_Message_Params paramsQOS0; IoT_Publish_Message_Params paramsQOS1; parseInputArgsForConnectParams(argc, argv); IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG); getcwd(CurrentWD, sizeof(CurrentWD)); snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME); snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME); snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME); IOT_DEBUG("rootCA %s", rootCA); IOT_DEBUG("clientCRT %s", clientCRT); IOT_DEBUG("clientKey %s", clientKey); mqttInitParams.enableAutoReconnect = false; // We enable this later below mqttInitParams.pHostURL = HostAddress; mqttInitParams.port = port; mqttInitParams.pRootCALocation = rootCA; mqttInitParams.pDeviceCertLocation = clientCRT; mqttInitParams.pDevicePrivateKeyLocation = clientKey; mqttInitParams.mqttCommandTimeout_ms = 20000; mqttInitParams.tlsHandshakeTimeout_ms = 5000; mqttInitParams.isSSLHostnameVerify = true; mqttInitParams.disconnectHandler = disconnectCallbackHandler; mqttInitParams.disconnectHandlerData = NULL; rc = aws_iot_mqtt_init(&client, &mqttInitParams); if(SUCCESS != rc) { IOT_ERROR("aws_iot_mqtt_init returned error : %d ", rc); return rc; } connectParams.keepAliveIntervalInSec = 10; connectParams.isCleanSession = true; connectParams.MQTTVersion = MQTT_3_1_1; connectParams.pClientID = AWS_IOT_MQTT_CLIENT_ID; connectParams.clientIDLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID); connectParams.isWillMsgPresent = false; IOT_INFO("Connecting..."); rc = aws_iot_mqtt_connect(&client, &connectParams); if(SUCCESS != rc) { IOT_ERROR("Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port); return rc; } /* * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h * #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL * #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL */ rc = aws_iot_mqtt_autoreconnect_set_status(&client, true); if(SUCCESS != rc) { IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); return rc; } IOT_INFO("Subscribing..."); rc = aws_iot_mqtt_subscribe(&client, "sdkTest/sub", 11, QOS0, iot_subscribe_callback_handler, NULL); if(SUCCESS != rc) { IOT_ERROR("Error subscribing : %d ", rc); return rc; } sprintf(cPayload, "%s : %d ", "hello from SDK", i); paramsQOS0.qos = QOS0; paramsQOS0.payload = (void *) cPayload; paramsQOS0.isRetained = 0; paramsQOS1.qos = QOS1; paramsQOS1.payload = (void *) cPayload; paramsQOS1.isRetained = 0; if(publishCount != 0) { infinitePublishFlag = false; } while((NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) && (publishCount > 0 || infinitePublishFlag)) { //Max time the yield function will wait for read messages rc = aws_iot_mqtt_yield(&client, 100); if(NETWORK_ATTEMPTING_RECONNECT == rc) { // If the client is attempting to reconnect we will skip the rest of the loop. continue; } IOT_INFO("-->sleep"); sleep(1); sprintf(cPayload, "%s : %d ", "hello from SDK QOS0", i++); paramsQOS0.payloadLen = strlen(cPayload); rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, ¶msQOS0); if(publishCount > 0) { publishCount--; } sprintf(cPayload, "%s : %d ", "hello from SDK QOS1", i++); paramsQOS1.payloadLen = strlen(cPayload); rc = aws_iot_mqtt_publish(&client, "sdkTest/sub", 11, ¶msQOS1); if (rc == MQTT_REQUEST_TIMEOUT_ERROR) { IOT_WARN("QOS1 publish ack not received.\n"); rc = SUCCESS; } if(publishCount > 0) { publishCount--; } } if(SUCCESS != rc) { IOT_ERROR("An error occurred in the loop.\n"); } else { IOT_INFO("Publish done\n"); } return rc; }