Microsoft Azure IoTHub client MQTT transport
Dependents: STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more
Diff: iothubtransport_mqtt_common.c
- Revision:
- 28:0cd355c3294e
- Parent:
- 27:04de3c0bf1db
- Child:
- 29:923be0c3998a
--- a/iothubtransport_mqtt_common.c Fri Aug 25 11:22:29 2017 -0700 +++ b/iothubtransport_mqtt_common.c Mon Sep 11 09:22:41 2017 -0700 @@ -178,6 +178,7 @@ bool log_trace; bool raw_trace; TICK_COUNTER_HANDLE msgTickCounter; + OPTIONHANDLER_HANDLE saved_tls_options; // Here are the options from the xio layer if any is saved. // Internal lists for message tracking PDLIST_ENTRY waitingToSend; @@ -251,6 +252,15 @@ } } +static void set_saved_tls_options(PMQTTTRANSPORT_HANDLE_DATA transport, OPTIONHANDLER_HANDLE new_options) +{ + if (transport->saved_tls_options != NULL) + { + OptionHandler_Destroy(transport->saved_tls_options); + } + transport->saved_tls_options = new_options; +} + int IoTHubTransport_MQTT_Common_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds) { int result; @@ -1222,7 +1232,7 @@ transport_data->isRecoverableError = false; } LogError("Connection Not Accepted: 0x%x: %s", connack->returnCode, retrieve_mqtt_return_codes(connack->returnCode) ); - (void)mqtt_client_disconnect(transport_data->mqttClient); + (void)mqtt_client_disconnect(transport_data->mqttClient, NULL, NULL); transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_NOT_CONNECTED; transport_data->currPacketState = PACKET_TYPE_ERROR; } @@ -1280,7 +1290,10 @@ static void DisconnectFromClient(PMQTTTRANSPORT_HANDLE_DATA transport_data) { - (void)mqtt_client_disconnect(transport_data->mqttClient); + OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport); + set_saved_tls_options(transport_data, options); + + (void)mqtt_client_disconnect(transport_data->mqttClient, NULL, NULL); xio_destroy(transport_data->xioTransport); transport_data->xioTransport = NULL; @@ -1471,7 +1484,44 @@ } else { - result = 0; + if (IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module) == IOTHUB_CREDENTIAL_TYPE_X509_ECC) + { + if (IoTHubClient_Auth_Set_xio_Certificate(transport_data->authorization_module, transport_data->xioTransport) != 0) + { + LogError("Unable to create the lower level TLS layer."); + result = __FAILURE__; + } + else + { + result = 0; + } + } + else + { + result = 0; + } + + if (result == 0) + { + if (transport_data->saved_tls_options != NULL) + { + if (OptionHandler_FeedOptions(transport_data->saved_tls_options, transport_data->xioTransport) != OPTIONHANDLER_OK) + { + LogError("Failed feeding existing options to new TLS instance."); + result = __FAILURE__; + } + else + { + // The tlsio has the options, so our copy can be deleted + set_saved_tls_options(transport_data, NULL); + result = 0; + } + } + else + { + result = 0; + } + } } } else @@ -1481,6 +1531,35 @@ return result; } +static int is_key_validate(const IOTHUBTRANSPORT_CONFIG* config) +{ + int result; + IOTHUB_CREDENTIAL_TYPE cred_type = IoTHubClient_Auth_Get_Credential_Type(config->auth_module_handle); + if (cred_type == IOTHUB_CREDENTIAL_TYPE_X509 || cred_type == IOTHUB_CREDENTIAL_TYPE_X509_ECC) + { + result = 0; + } + else + { + if (config->upperConfig->deviceKey == NULL && config->upperConfig->deviceSasToken == NULL) + { + if (IoTHubClient_Auth_Get_DeviceKey(config->auth_module_handle) == NULL) + { + result = __FAILURE__; + } + else + { + result = 0; + } + } + else + { + result = 0; + } + } + return result; +} + static int SendMqttConnectMsg(PMQTTTRANSPORT_HANDLE_DATA transport_data) { int result; @@ -1489,14 +1568,14 @@ result = 0; IOTHUB_CREDENTIAL_TYPE cred_type = IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module); - if (cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY) + if (cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY || cred_type == IOTHUB_CREDENTIAL_TYPE_DEVICE_AUTH) { size_t secSinceEpoch = (size_t)(difftime(get_time(NULL), EPOCH_TIME_T_VALUE) + 0); size_t expiryTime = secSinceEpoch + SAS_TOKEN_DEFAULT_LIFETIME; sasToken = IoTHubClient_Auth_Get_SasToken(transport_data->authorization_module, STRING_c_str(transport_data->devicesPath), expiryTime); if (sasToken == NULL) { - LogError("failure getting sas Token."); + LogError("failure getting sas token from IoTHubClient_Auth_Get_SasToken."); result = __FAILURE__; } } @@ -1666,7 +1745,9 @@ if ((current_time - transport_data->mqtt_connect_time) / 1000 > (SAS_TOKEN_DEFAULT_LIFETIME*SAS_REFRESH_MULTIPLIER)) { /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_07_058: [ If the sas token has timed out IoTHubTransport_MQTT_Common_DoWork shall disconnect from the mqtt client and destroy the transport information and wait for reconnect. ] */ - (void)mqtt_client_disconnect(transport_data->mqttClient); + OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport); + set_saved_tls_options(transport_data, options); + (void)mqtt_client_disconnect(transport_data->mqttClient, NULL, NULL); xio_destroy(transport_data->xioTransport); transport_data->xioTransport = NULL; @@ -1852,15 +1933,22 @@ LogError("Invalid Argument: Config Parameter is NULL."); result = NULL; } + /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [If the parameter config's variables upperConfig, auth_module_handle or waitingToSend are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */ + else if (config->auth_module_handle == NULL) + { + LogError("Invalid Argument: auth_module_handle is NULL)"); + result = NULL; + } /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [If the parameter config's variables upperConfig or waitingToSend are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */ /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [If the upperConfig's variables deviceId, both deviceKey and deviceSasToken, iotHubName, protocol, or iotHubSuffix are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */ /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_03_003: [If both deviceKey & deviceSasToken fields are NOT NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */ else if (config->upperConfig == NULL || config->upperConfig->protocol == NULL || config->upperConfig->deviceId == NULL || - ((config->upperConfig->deviceKey != NULL) && (config->upperConfig->deviceSasToken != NULL)) || - config->upperConfig->iotHubName == NULL || - config->upperConfig->iotHubSuffix == NULL) + ((config->upperConfig->deviceKey != NULL) && (config->upperConfig->deviceSasToken != NULL)) || + //is_key_validate(config) != 0 || + config->upperConfig->iotHubName == NULL || + config->upperConfig->iotHubSuffix == NULL) { LogError("Invalid Argument: upperConfig structure contains an invalid parameter"); result = NULL; @@ -1871,12 +1959,6 @@ LogError("Invalid Argument: waitingToSend is NULL)"); result = NULL; } - /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [If the parameter config's variables upperConfig, auth_module_handle or waitingToSend are NULL then IoTHubTransport_MQTT_Common_Create shall return NULL.] */ - else if (config->auth_module_handle == NULL) - { - LogError("Invalid Argument: auth_module_handle is NULL)"); - result = NULL; - } /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_006: [If the upperConfig's variables deviceId is an empty strings or length is greater then 128 then IoTHubTransport_MQTT_Common_Create shall return NULL.] */ else if ( ( (deviceIdSize = strlen(config->upperConfig->deviceId)) > 128U) || (deviceIdSize == 0) ) { @@ -1957,6 +2039,8 @@ STRING_delete(transport_data->topic_NotifyState); STRING_delete(transport_data->topic_DeviceMethods); + set_saved_tls_options(transport_data, NULL); + tickcounter_destroy(transport_data->msgTickCounter); /* Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_01_012: [ `IoTHubTransport_MQTT_Common_Destroy` shall free the stored proxy options. ]*/ free_proxy_data(transport_data);