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; } } }
void publishMessage(char* message) { IoT_Error_t rc = FAILURE; IoT_Publish_Message_Params paramsQOS0; paramsQOS0.qos = QOS0; paramsQOS0.payload = (void *) message; paramsQOS0.isRetained = 0; while (NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS != rc) { //Max time the yield function will wait for read messages rc = aws_iot_mqtt_yield(&mqttClient, 1000); if (NETWORK_ATTEMPTING_RECONNECT == rc) { // If the client is attempting to reconnect we will skip the rest of the loop. continue; } paramsQOS0.payloadLen = strlen(message); do { rc = aws_iot_mqtt_publish(&mqttClient, publishTopicName, strlen(publishTopicName), ¶msQOS0); } while (MQTT_REQUEST_TIMEOUT_ERROR == rc); } if (SUCCESS != rc) { IOT_ERROR("An error occurred while publishing message.\n"); } }
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; 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) { IOT_ERROR(" failed\n ! mbedtls_ssl_write returned -0x%x\n\n", -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; }
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; } } }
bool connectToThingAndSubscribeToTopic(int argc, char **argv) { IoT_Error_t rc = FAILURE; char rootCA[PATH_MAX + 1]; char clientCRT[PATH_MAX + 1]; char clientKey[PATH_MAX + 1]; char CurrentWD[PATH_MAX + 1]; IoT_Publish_Message_Params paramsQOS0; 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); char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER]; size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]); char *pJsonStringToUpdate; ShadowInitParameters_t sp = ShadowInitParametersDefault; IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault; 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 false; } ShadowConnectParameters_t scp = ShadowConnectParametersDefault; IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault; 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 false; } 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(&mqttClient, &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(&mqttClient, &connectParams); if (SUCCESS != rc) { IOT_ERROR("Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port); return rc; } // Enable Auto Reconnect functionality rc = aws_iot_shadow_set_autoreconnect_status(&mqttClient, true); if (SUCCESS != rc) { IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); return false; } rc = aws_iot_mqtt_autoreconnect_set_status(&mqttClient, true); if (SUCCESS != rc) { IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc); return false; } IOT_INFO("Subscribing..."); rc = aws_iot_mqtt_subscribe(&mqttClient, subscribeTopicName, strlen(subscribeTopicName), QOS0, iot_subscribe_callback_handler, NULL); if (SUCCESS != rc) { IOT_ERROR("Error subscribing : %d ", rc); return false; } return true; }
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; }
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; }
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; }