Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: STM32F746_iothub_client_sample_mqtt FXOS8700CQ_To_Azure_IoT f767zi_mqtt FXOS8700CQ_To_Azure_IoT ... more
Revision 41:410450f16a9f, committed 2018-09-11
- Comitter:
- AzureIoTClient
- Date:
- Tue Sep 11 11:12:42 2018 -0700
- Parent:
- 40:cb03d6a6f46d
- Commit message:
- 1.2.9
Changed in this revision
--- a/internal/iothub_client_retry_control.h Tue Jun 26 19:14:02 2018 -0700
+++ b/internal/iothub_client_retry_control.h Tue Sep 11 11:12:42 2018 -0700
@@ -23,9 +23,9 @@
typedef enum RETRY_ACTION_TAG
{
- RETRY_ACTION_RETRY_NOW,
- RETRY_ACTION_RETRY_LATER,
- RETRY_ACTION_STOP_RETRYING
+ RETRY_ACTION_RETRY_NOW,
+ RETRY_ACTION_RETRY_LATER,
+ RETRY_ACTION_STOP_RETRYING
} RETRY_ACTION;
struct RETRY_CONTROL_INSTANCE_TAG;
@@ -44,4 +44,4 @@
}
#endif
-#endif // IOTHUB_CLIENT_RETRY_CONTROL
\ No newline at end of file
+#endif // IOTHUB_CLIENT_RETRY_CONTROL
--- a/iothub_client_retry_control.c Tue Jun 26 19:14:02 2018 -0700
+++ b/iothub_client_retry_control.c Tue Sep 11 11:12:42 2018 -0700
@@ -15,16 +15,16 @@
typedef struct RETRY_CONTROL_INSTANCE_TAG
{
- IOTHUB_CLIENT_RETRY_POLICY policy;
- unsigned int max_retry_time_in_secs;
+ IOTHUB_CLIENT_RETRY_POLICY policy;
+ unsigned int max_retry_time_in_secs;
- unsigned int initial_wait_time_in_secs;
- unsigned int max_jitter_percent;
+ unsigned int initial_wait_time_in_secs;
+ unsigned int max_jitter_percent;
- unsigned int retry_count;
- time_t first_retry_time;
- time_t last_retry_time;
- unsigned int current_wait_time_in_secs;
+ unsigned int retry_count;
+ time_t first_retry_time;
+ time_t last_retry_time;
+ unsigned int current_wait_time_in_secs;
} RETRY_CONTROL_INSTANCE;
typedef int (*RETRY_ACTION_EVALUATION_FUNCTION)(RETRY_CONTROL_INSTANCE* retry_state, RETRY_ACTION* retry_action);
@@ -36,164 +36,164 @@
static void* retry_control_clone_option(const char* name, const void* value)
{
- void* result;
+ void* result;
- if ((name == NULL) || (value == NULL))
- {
- LogError("Failed to clone option (either name (%p) or value (%p) are NULL)", name, value);
- result = NULL;
- }
- else if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0 ||
- strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
- {
- unsigned int* cloned_value;
+ if ((name == NULL) || (value == NULL))
+ {
+ LogError("Failed to clone option (either name (%p) or value (%p) are NULL)", name, value);
+ result = NULL;
+ }
+ else if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0 ||
+ strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
+ {
+ unsigned int* cloned_value;
- if ((cloned_value = (unsigned int*)malloc(sizeof(unsigned int))) == NULL)
- {
- LogError("Failed to clone option '%p' (malloc failed)", name);
- result = NULL;
- }
- else
- {
- *cloned_value = *(unsigned int*)value;
+ if ((cloned_value = (unsigned int*)malloc(sizeof(unsigned int))) == NULL)
+ {
+ LogError("Failed to clone option '%p' (malloc failed)", name);
+ result = NULL;
+ }
+ else
+ {
+ *cloned_value = *(unsigned int*)value;
- result = (void*)cloned_value;
- }
- }
- else
- {
- LogError("Failed to clone option (option with name '%s' is not suppported)", name);
- result = NULL;
- }
+ result = (void*)cloned_value;
+ }
+ }
+ else
+ {
+ LogError("Failed to clone option (option with name '%s' is not suppported)", name);
+ result = NULL;
+ }
- return result;
+ return result;
}
static void retry_control_destroy_option(const char* name, const void* value)
{
- if ((name == NULL) || (value == NULL))
- {
- LogError("Failed to destroy option (either name (%p) or value (%p) are NULL)", name, value);
- }
- else if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0 ||
- strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
- {
- free((void*)value);
- }
- else
- {
- LogError("Failed to destroy option (option with name '%s' is not suppported)", name);
- }
+ if ((name == NULL) || (value == NULL))
+ {
+ LogError("Failed to destroy option (either name (%p) or value (%p) are NULL)", name, value);
+ }
+ else if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0 ||
+ strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
+ {
+ free((void*)value);
+ }
+ else
+ {
+ LogError("Failed to destroy option (option with name '%s' is not suppported)", name);
+ }
}
// ========== _should_retry() Auxiliary Functions ========== //
static int evaluate_retry_action(RETRY_CONTROL_INSTANCE* retry_control, RETRY_ACTION* retry_action)
{
- int result;
+ int result;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_019: [If `retry_control->retry_count` is 0, `retry_action` shall be set to RETRY_ACTION_RETRY_NOW]
- if (retry_control->retry_count == 0)
- {
- *retry_action = RETRY_ACTION_RETRY_NOW;
- result = RESULT_OK;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_020: [If `retry_control->last_retry_time` is INDEFINITE_TIME and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, the evaluation function shall return non-zero]
- else if (retry_control->last_retry_time == INDEFINITE_TIME &&
- retry_control->policy != IOTHUB_CLIENT_RETRY_IMMEDIATE)
- {
- LogError("Failed to evaluate retry action (last_retry_time is INDEFINITE_TIME)");
- result = __FAILURE__;
- }
- else
- {
- time_t current_time;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_019: [If `retry_control->retry_count` is 0, `retry_action` shall be set to RETRY_ACTION_RETRY_NOW]
+ if (retry_control->retry_count == 0)
+ {
+ *retry_action = RETRY_ACTION_RETRY_NOW;
+ result = RESULT_OK;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_020: [If `retry_control->last_retry_time` is INDEFINITE_TIME and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, the evaluation function shall return non-zero]
+ else if (retry_control->last_retry_time == INDEFINITE_TIME &&
+ retry_control->policy != IOTHUB_CLIENT_RETRY_IMMEDIATE)
+ {
+ LogError("Failed to evaluate retry action (last_retry_time is INDEFINITE_TIME)");
+ result = __FAILURE__;
+ }
+ else
+ {
+ time_t current_time;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_021: [`current_time` shall be set using get_time()]
- if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_022: [If get_time() fails, the evaluation function shall return non-zero]
- LogError("Failed to evaluate retry action (get_time() failed)");
- result = __FAILURE__;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_023: [If `retry_control->max_retry_time_in_secs` is not 0 and (`current_time` - `retry_control->first_retry_time`) is greater than or equal to `retry_control->max_retry_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_STOP_RETRYING]
- else if (retry_control->max_retry_time_in_secs > 0 &&
- get_difftime(current_time, retry_control->first_retry_time) >= retry_control->max_retry_time_in_secs)
- {
- *retry_action = RETRY_ACTION_STOP_RETRYING;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_021: [`current_time` shall be set using get_time()]
+ if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_022: [If get_time() fails, the evaluation function shall return non-zero]
+ LogError("Failed to evaluate retry action (get_time() failed)");
+ result = __FAILURE__;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_023: [If `retry_control->max_retry_time_in_secs` is not 0 and (`current_time` - `retry_control->first_retry_time`) is greater than or equal to `retry_control->max_retry_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_STOP_RETRYING]
+ else if (retry_control->max_retry_time_in_secs > 0 &&
+ get_difftime(current_time, retry_control->first_retry_time) >= retry_control->max_retry_time_in_secs)
+ {
+ *retry_action = RETRY_ACTION_STOP_RETRYING;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
- result = RESULT_OK;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_028: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_IMMEDIATE, retry_action shall be set to RETRY_ACTION_RETRY_NOW]
- else if (retry_control->policy == IOTHUB_CLIENT_RETRY_IMMEDIATE)
- {
- *retry_action = RETRY_ACTION_RETRY_NOW;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+ result = RESULT_OK;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_028: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_IMMEDIATE, retry_action shall be set to RETRY_ACTION_RETRY_NOW]
+ else if (retry_control->policy == IOTHUB_CLIENT_RETRY_IMMEDIATE)
+ {
+ *retry_action = RETRY_ACTION_RETRY_NOW;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
- result = RESULT_OK;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_024: [Otherwise, if (`current_time` - `retry_control->last_retry_time`) is less than `retry_control->current_wait_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_RETRY_LATER]
- else if (get_difftime(current_time, retry_control->last_retry_time) < retry_control->current_wait_time_in_secs)
- {
- *retry_action = RETRY_ACTION_RETRY_LATER;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+ result = RESULT_OK;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_024: [Otherwise, if (`current_time` - `retry_control->last_retry_time`) is less than `retry_control->current_wait_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_RETRY_LATER]
+ else if (get_difftime(current_time, retry_control->last_retry_time) < retry_control->current_wait_time_in_secs)
+ {
+ *retry_action = RETRY_ACTION_RETRY_LATER;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
- result = RESULT_OK;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_025: [Otherwise, if (`current_time` - `retry_control->last_retry_time`) is greater or equal to `retry_control->current_wait_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_RETRY_NOW]
- else
- {
- *retry_action = RETRY_ACTION_RETRY_NOW;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+ result = RESULT_OK;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_025: [Otherwise, if (`current_time` - `retry_control->last_retry_time`) is greater or equal to `retry_control->current_wait_time_in_secs`, `retry_action` shall be set to RETRY_ACTION_RETRY_NOW]
+ else
+ {
+ *retry_action = RETRY_ACTION_RETRY_NOW;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
- result = RESULT_OK;
- }
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_026: [If no errors occur, the evaluation function shall return 0]
+ result = RESULT_OK;
+ }
+ }
- return result;
+ return result;
}
static unsigned int calculate_next_wait_time(RETRY_CONTROL_INSTANCE* retry_control)
{
- unsigned int result;
+ unsigned int result;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_029: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_INTERVAL, `calculate_next_wait_time` shall return `retry_control->initial_wait_time_in_secs`]
- if (retry_control->policy == IOTHUB_CLIENT_RETRY_INTERVAL)
- {
- result = retry_control->initial_wait_time_in_secs;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_030: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_LINEAR_BACKOFF, `calculate_next_wait_time` shall return (`retry_control->initial_wait_time_in_secs` * (`retry_control->retry_count`))]
- else if (retry_control->policy == IOTHUB_CLIENT_RETRY_LINEAR_BACKOFF)
- {
- result = retry_control->initial_wait_time_in_secs * (retry_control->retry_count);
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_031: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF, `calculate_next_wait_time` shall return (pow(2, `retry_control->retry_count` - 1) * `retry_control->initial_wait_time_in_secs`)]
- else if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF)
- {
- result = (unsigned int)(pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs);
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_032: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, `calculate_next_wait_time` shall return ((pow(2, `retry_control->retry_count` - 1) * `retry_control->initial_wait_time_in_secs`) * (1 + (`retry_control->max_jitter_percent` / 100) * (rand() / RAND_MAX)))]
- else if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER)
- {
- double jitter_percent = (retry_control->max_jitter_percent / 100.0) * (rand() / ((double)RAND_MAX));
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_029: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_INTERVAL, `calculate_next_wait_time` shall return `retry_control->initial_wait_time_in_secs`]
+ if (retry_control->policy == IOTHUB_CLIENT_RETRY_INTERVAL)
+ {
+ result = retry_control->initial_wait_time_in_secs;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_030: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_LINEAR_BACKOFF, `calculate_next_wait_time` shall return (`retry_control->initial_wait_time_in_secs` * (`retry_control->retry_count`))]
+ else if (retry_control->policy == IOTHUB_CLIENT_RETRY_LINEAR_BACKOFF)
+ {
+ result = retry_control->initial_wait_time_in_secs * (retry_control->retry_count);
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_031: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF, `calculate_next_wait_time` shall return (pow(2, `retry_control->retry_count` - 1) * `retry_control->initial_wait_time_in_secs`)]
+ else if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF)
+ {
+ result = (unsigned int)(pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs);
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_032: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, `calculate_next_wait_time` shall return ((pow(2, `retry_control->retry_count` - 1) * `retry_control->initial_wait_time_in_secs`) * (1 + (`retry_control->max_jitter_percent` / 100) * (rand() / RAND_MAX)))]
+ else if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER)
+ {
+ double jitter_percent = (retry_control->max_jitter_percent / 100.0) * (rand() / ((double)RAND_MAX));
- result = (unsigned int)(pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs * (1 + jitter_percent));
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_033: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_RANDOM, `calculate_next_wait_time` shall return (`retry_control->initial_wait_time_in_secs` * (rand() / RAND_MAX))]
- else if (retry_control->policy == IOTHUB_CLIENT_RETRY_RANDOM)
- {
- double random_percent = ((double)rand() / (double)RAND_MAX);
- result = (unsigned int)(retry_control->initial_wait_time_in_secs * random_percent);
- }
- else
- {
- LogError("Failed to calculate the next wait time (policy %d is not expected)", retry_control->policy);
+ result = (unsigned int)(pow(2, retry_control->retry_count - 1) * retry_control->initial_wait_time_in_secs * (1 + jitter_percent));
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_033: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_RANDOM, `calculate_next_wait_time` shall return (`retry_control->initial_wait_time_in_secs` * (rand() / RAND_MAX))]
+ else if (retry_control->policy == IOTHUB_CLIENT_RETRY_RANDOM)
+ {
+ double random_percent = ((double)rand() / (double)RAND_MAX);
+ result = (unsigned int)(retry_control->initial_wait_time_in_secs * random_percent);
+ }
+ else
+ {
+ LogError("Failed to calculate the next wait time (policy %d is not expected)", retry_control->policy);
- result = 0;
- }
+ result = 0;
+ }
- return result;
+ return result;
}
@@ -201,314 +201,314 @@
int is_timeout_reached(time_t start_time, unsigned int timeout_in_secs, bool* is_timed_out)
{
- int result;
+ int result;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_057: [If `start_time` is INDEFINITE_TIME, `is_timeout_reached` shall fail and return non-zero]
- if (start_time == INDEFINITE_TIME)
- {
- LogError("Failed to verify timeout (start_time is INDEFINITE)");
- result = __FAILURE__;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_058: [If `is_timed_out` is NULL, `is_timeout_reached` shall fail and return non-zero]
- else if (is_timed_out == NULL)
- {
- LogError("Failed to verify timeout (is_timed_out is NULL)");
- result = __FAILURE__;
- }
- else
- {
- time_t current_time;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_057: [If `start_time` is INDEFINITE_TIME, `is_timeout_reached` shall fail and return non-zero]
+ if (start_time == INDEFINITE_TIME)
+ {
+ LogError("Failed to verify timeout (start_time is INDEFINITE)");
+ result = __FAILURE__;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_058: [If `is_timed_out` is NULL, `is_timeout_reached` shall fail and return non-zero]
+ else if (is_timed_out == NULL)
+ {
+ LogError("Failed to verify timeout (is_timed_out is NULL)");
+ result = __FAILURE__;
+ }
+ else
+ {
+ time_t current_time;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_059: [`is_timeout_reached` shall obtain the `current_time` using get_time()]
- if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_060: [If get_time() fails, `is_timeout_reached` shall fail and return non-zero]
- LogError("Failed to verify timeout (get_time failed)");
- result = __FAILURE__;
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_061: [If (`current_time` - `start_time`) is greater or equal to `timeout_in_secs`, `is_timed_out` shall be set to true]
- if (get_difftime(current_time, start_time) >= timeout_in_secs)
- {
- *is_timed_out = true;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_062: [If (`current_time` - `start_time`) is less than `timeout_in_secs`, `is_timed_out` shall be set to false]
- else
- {
- *is_timed_out = false;
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_059: [`is_timeout_reached` shall obtain the `current_time` using get_time()]
+ if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_060: [If get_time() fails, `is_timeout_reached` shall fail and return non-zero]
+ LogError("Failed to verify timeout (get_time failed)");
+ result = __FAILURE__;
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_061: [If (`current_time` - `start_time`) is greater or equal to `timeout_in_secs`, `is_timed_out` shall be set to true]
+ if (get_difftime(current_time, start_time) >= timeout_in_secs)
+ {
+ *is_timed_out = true;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_062: [If (`current_time` - `start_time`) is less than `timeout_in_secs`, `is_timed_out` shall be set to false]
+ else
+ {
+ *is_timed_out = false;
+ }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_063: [If no errors occur, `is_timeout_reached` shall return 0]
- result = RESULT_OK;
- }
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_063: [If no errors occur, `is_timeout_reached` shall return 0]
+ result = RESULT_OK;
+ }
+ }
- return result;
+ return result;
}
void retry_control_reset(RETRY_CONTROL_HANDLE retry_control_handle)
{
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_034: [If `retry_control_handle` is NULL, `retry_control_reset` shall return]
- if (retry_control_handle == NULL)
- {
- LogError("Failed to reset the retry control (retry_state_handle is NULL)");
- }
- else
- {
- RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_034: [If `retry_control_handle` is NULL, `retry_control_reset` shall return]
+ if (retry_control_handle == NULL)
+ {
+ LogError("Failed to reset the retry control (retry_state_handle is NULL)");
+ }
+ else
+ {
+ RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_035: [`retry_control` shall have fields `retry_count` and `current_wait_time_in_secs` set to 0 (zero), `first_retry_time` and `last_retry_time` set to INDEFINITE_TIME]
- retry_control->retry_count = 0;
- retry_control->current_wait_time_in_secs = 0;
- retry_control->first_retry_time = INDEFINITE_TIME;
- retry_control->last_retry_time = INDEFINITE_TIME;
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_035: [`retry_control` shall have fields `retry_count` and `current_wait_time_in_secs` set to 0 (zero), `first_retry_time` and `last_retry_time` set to INDEFINITE_TIME]
+ retry_control->retry_count = 0;
+ retry_control->current_wait_time_in_secs = 0;
+ retry_control->first_retry_time = INDEFINITE_TIME;
+ retry_control->last_retry_time = INDEFINITE_TIME;
+ }
}
RETRY_CONTROL_HANDLE retry_control_create(IOTHUB_CLIENT_RETRY_POLICY policy, unsigned int max_retry_time_in_secs)
{
- RETRY_CONTROL_INSTANCE* retry_control;
+ RETRY_CONTROL_INSTANCE* retry_control;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_002: [`retry_control_create` shall allocate memory for the retry control instance structure (a.k.a. `retry_control`)]
- if ((retry_control = (RETRY_CONTROL_INSTANCE*)malloc(sizeof(RETRY_CONTROL_INSTANCE))) == NULL)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_003: [If malloc fails, `retry_control_create` shall fail and return NULL]
- LogError("Failed creating the retry control (malloc failed)");
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_004: [The parameters passed to `retry_control_create` shall be saved into `retry_control`]
- memset(retry_control, 0, sizeof(RETRY_CONTROL_INSTANCE));
- retry_control->policy = policy;
- retry_control->max_retry_time_in_secs = max_retry_time_in_secs;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_002: [`retry_control_create` shall allocate memory for the retry control instance structure (a.k.a. `retry_control`)]
+ if ((retry_control = (RETRY_CONTROL_INSTANCE*)malloc(sizeof(RETRY_CONTROL_INSTANCE))) == NULL)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_003: [If malloc fails, `retry_control_create` shall fail and return NULL]
+ LogError("Failed creating the retry control (malloc failed)");
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_004: [The parameters passed to `retry_control_create` shall be saved into `retry_control`]
+ memset(retry_control, 0, sizeof(RETRY_CONTROL_INSTANCE));
+ retry_control->policy = policy;
+ retry_control->max_retry_time_in_secs = max_retry_time_in_secs;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_005: [If `policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF or IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, `retry_control->initial_wait_time_in_secs` shall be set to 1]
- if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF ||
- retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER)
- {
- retry_control->initial_wait_time_in_secs = 1;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_006: [Otherwise `retry_control->initial_wait_time_in_secs` shall be set to 5]
- else
- {
- retry_control->initial_wait_time_in_secs = 5;
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_005: [If `policy` is IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF or IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, `retry_control->initial_wait_time_in_secs` shall be set to 1]
+ if (retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF ||
+ retry_control->policy == IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER)
+ {
+ retry_control->initial_wait_time_in_secs = 1;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_006: [Otherwise `retry_control->initial_wait_time_in_secs` shall be set to 5]
+ else
+ {
+ retry_control->initial_wait_time_in_secs = 5;
+ }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_007: [`retry_control->max_jitter_percent` shall be set to 5]
- retry_control->max_jitter_percent = 5;
-
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_008: [The remaining fields in `retry_control` shall be initialized according to retry_control_reset()]
- retry_control_reset(retry_control);
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_007: [`retry_control->max_jitter_percent` shall be set to 5]
+ retry_control->max_jitter_percent = 5;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_009: [If no errors occur, `retry_control_create` shall return a handle to `retry_control`]
- return (RETRY_CONTROL_HANDLE)retry_control;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_008: [The remaining fields in `retry_control` shall be initialized according to retry_control_reset()]
+ retry_control_reset(retry_control);
+ }
+
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_009: [If no errors occur, `retry_control_create` shall return a handle to `retry_control`]
+ return (RETRY_CONTROL_HANDLE)retry_control;
}
void retry_control_destroy(RETRY_CONTROL_HANDLE retry_control_handle)
{
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_055: [If `retry_control_handle` is NULL, `retry_control_destroy` shall return]
- if (retry_control_handle == NULL)
- {
- LogError("Failed to destroy the retry control (retry_control_handle is NULL)");
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_056: [`retry_control_destroy` shall destroy `retry_control_handle` using free()]
- free(retry_control_handle);
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_055: [If `retry_control_handle` is NULL, `retry_control_destroy` shall return]
+ if (retry_control_handle == NULL)
+ {
+ LogError("Failed to destroy the retry control (retry_control_handle is NULL)");
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_056: [`retry_control_destroy` shall destroy `retry_control_handle` using free()]
+ free(retry_control_handle);
+ }
}
int retry_control_should_retry(RETRY_CONTROL_HANDLE retry_control_handle, RETRY_ACTION* retry_action)
{
- int result;
+ int result;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_010: [If `retry_control_handle` or `retry_action` are NULL, `retry_control_should_retry` shall fail and return non-zero]
- if ((retry_control_handle == NULL) || (retry_action == NULL))
- {
- LogError("Failed to evaluate if retry should be attempted (either retry_control_handle (%p) or retry_action (%p) are NULL)", retry_control_handle, retry_action);
- result = __FAILURE__;
- }
- else
- {
- RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_010: [If `retry_control_handle` or `retry_action` are NULL, `retry_control_should_retry` shall fail and return non-zero]
+ if ((retry_control_handle == NULL) || (retry_action == NULL))
+ {
+ LogError("Failed to evaluate if retry should be attempted (either retry_control_handle (%p) or retry_action (%p) are NULL)", retry_control_handle, retry_action);
+ result = __FAILURE__;
+ }
+ else
+ {
+ RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_027: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_NONE, retry_action shall be set to RETRY_ACTION_STOP_RETRYING and return immediatelly with result 0]
- if (retry_control->policy == IOTHUB_CLIENT_RETRY_NONE)
- {
- *retry_action = RETRY_ACTION_STOP_RETRYING;
- result = RESULT_OK;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_011: [If `retry_control->first_retry_time` is INDEFINITE_TIME, it shall be set using get_time()]
- else if (retry_control->first_retry_time == INDEFINITE_TIME && (retry_control->first_retry_time = get_time(NULL)) == INDEFINITE_TIME)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_012: [If get_time() fails, `retry_control_should_retry` shall fail and return non-zero]
- LogError("Failed to evaluate if retry should be attempted (get_time() failed)");
- result = __FAILURE__;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_013: [evaluate_retry_action() shall be invoked]
- else if (evaluate_retry_action(retry_control, retry_action) != RESULT_OK)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_014: [If evaluate_retry_action() fails, `retry_control_should_retry` shall fail and return non-zero]
- LogError("Failed to evaluate if retry should be attempted (evaluate_retry_action() failed)");
- result = __FAILURE__;
- }
- else
- {
- if (*retry_action == RETRY_ACTION_RETRY_NOW)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_015: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW, `retry_control->retry_count` shall be incremented by 1]
- retry_control->retry_count++;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_027: [If `retry_control->policy` is IOTHUB_CLIENT_RETRY_NONE, retry_action shall be set to RETRY_ACTION_STOP_RETRYING and return immediatelly with result 0]
+ if (retry_control->policy == IOTHUB_CLIENT_RETRY_NONE)
+ {
+ *retry_action = RETRY_ACTION_STOP_RETRYING;
+ result = RESULT_OK;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_011: [If `retry_control->first_retry_time` is INDEFINITE_TIME, it shall be set using get_time()]
+ else if (retry_control->first_retry_time == INDEFINITE_TIME && (retry_control->first_retry_time = get_time(NULL)) == INDEFINITE_TIME)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_012: [If get_time() fails, `retry_control_should_retry` shall fail and return non-zero]
+ LogError("Failed to evaluate if retry should be attempted (get_time() failed)");
+ result = __FAILURE__;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_013: [evaluate_retry_action() shall be invoked]
+ else if (evaluate_retry_action(retry_control, retry_action) != RESULT_OK)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_014: [If evaluate_retry_action() fails, `retry_control_should_retry` shall fail and return non-zero]
+ LogError("Failed to evaluate if retry should be attempted (evaluate_retry_action() failed)");
+ result = __FAILURE__;
+ }
+ else
+ {
+ if (*retry_action == RETRY_ACTION_RETRY_NOW)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_015: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW, `retry_control->retry_count` shall be incremented by 1]
+ retry_control->retry_count++;
- if (retry_control->policy != IOTHUB_CLIENT_RETRY_IMMEDIATE)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_016: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, `retry_control->last_retry_time` shall be set using get_time()]
- retry_control->last_retry_time = get_time(NULL);
+ if (retry_control->policy != IOTHUB_CLIENT_RETRY_IMMEDIATE)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_016: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, `retry_control->last_retry_time` shall be set using get_time()]
+ retry_control->last_retry_time = get_time(NULL);
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_017: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, `retry_control->current_wait_time_in_secs` shall be set using calculate_next_wait_time()]
- retry_control->current_wait_time_in_secs = calculate_next_wait_time(retry_control);
- }
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_017: [If `retry_action` is set to RETRY_ACTION_RETRY_NOW and policy is not IOTHUB_CLIENT_RETRY_IMMEDIATE, `retry_control->current_wait_time_in_secs` shall be set using calculate_next_wait_time()]
+ retry_control->current_wait_time_in_secs = calculate_next_wait_time(retry_control);
+ }
+ }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_018: [If no errors occur, `retry_control_should_retry` shall return 0]
- result = RESULT_OK;
- }
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_018: [If no errors occur, `retry_control_should_retry` shall return 0]
+ result = RESULT_OK;
+ }
+ }
- return result;
+ return result;
}
int retry_control_set_option(RETRY_CONTROL_HANDLE retry_control_handle, const char* name, const void* value)
{
- int result;
+ int result;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_036: [If `retry_control_handle`, `name` or `value` are NULL, `retry_control_set_option` shall fail and return non-zero]
- if (retry_control_handle == NULL || name == NULL || value == NULL)
- {
- LogError("Failed to set option (either retry_state_handle (%p), name (%p) or value (%p) are NULL)", retry_control_handle, name, value);
- result = __FAILURE__;
- }
- else
- {
- RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_036: [If `retry_control_handle`, `name` or `value` are NULL, `retry_control_set_option` shall fail and return non-zero]
+ if (retry_control_handle == NULL || name == NULL || value == NULL)
+ {
+ LogError("Failed to set option (either retry_state_handle (%p), name (%p) or value (%p) are NULL)", retry_control_handle, name, value);
+ result = __FAILURE__;
+ }
+ else
+ {
+ RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
- if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0)
- {
- unsigned int cast_value = *((unsigned int*)value);
+ if (strcmp(RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, name) == 0)
+ {
+ unsigned int cast_value = *((unsigned int*)value);
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_037: [If `name` is "initial_wait_time_in_secs" and `value` is less than 1, `retry_control_set_option` shall fail and return non-zero]
- if (cast_value < 1)
- {
- LogError("Failed to set option '%s' (value must be equal or greater to 1)", name);
- result = __FAILURE__;
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_038: [If `name` is "initial_wait_time_in_secs", `value` shall be saved on `retry_control->initial_wait_time_in_secs`]
- retry_control->initial_wait_time_in_secs = cast_value;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_037: [If `name` is "initial_wait_time_in_secs" and `value` is less than 1, `retry_control_set_option` shall fail and return non-zero]
+ if (cast_value < 1)
+ {
+ LogError("Failed to set option '%s' (value must be equal or greater to 1)", name);
+ result = __FAILURE__;
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_038: [If `name` is "initial_wait_time_in_secs", `value` shall be saved on `retry_control->initial_wait_time_in_secs`]
+ retry_control->initial_wait_time_in_secs = cast_value;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, retry_control_set_option shall return 0]
- result = RESULT_OK;
- }
- }
- else if (strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
- {
- unsigned int cast_value = *((unsigned int*)value);
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, retry_control_set_option shall return 0]
+ result = RESULT_OK;
+ }
+ }
+ else if (strcmp(RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, name) == 0)
+ {
+ unsigned int cast_value = *((unsigned int*)value);
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_039: [If `name` is "max_jitter_percent" and `value` is less than 0 or greater than 100, `retry_control_set_option` shall fail and return non-zero]
- if (cast_value > 100) // it's unsigned int, it doesn't need to be checked for less than zero.
- {
- LogError("Failed to set option '%s' (value must be in the range 0 to 100)", name);
- result = __FAILURE__;
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_040: [If `name` is "max_jitter_percent", value shall be saved on `retry_control->max_jitter_percent`]
- retry_control->max_jitter_percent = cast_value;
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_039: [If `name` is "max_jitter_percent" and `value` is less than 0 or greater than 100, `retry_control_set_option` shall fail and return non-zero]
+ if (cast_value > 100) // it's unsigned int, it doesn't need to be checked for less than zero.
+ {
+ LogError("Failed to set option '%s' (value must be in the range 0 to 100)", name);
+ result = __FAILURE__;
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_040: [If `name` is "max_jitter_percent", value shall be saved on `retry_control->max_jitter_percent`]
+ retry_control->max_jitter_percent = cast_value;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, retry_control_set_option shall return 0]
- result = RESULT_OK;
- }
- }
- else if (strcmp(RETRY_CONTROL_OPTION_SAVED_OPTIONS, name) == 0)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_041: [If `name` is "retry_control_options", value shall be fed to `retry_control` using OptionHandler_FeedOptions]
- if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, retry_control_handle) != OPTIONHANDLER_OK)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_042: [If OptionHandler_FeedOptions fails, `retry_control_set_option` shall fail and return non-zero]
- LogError("messenger_set_option failed (OptionHandler_FeedOptions failed)");
- result = __FAILURE__;
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, `retry_control_set_option` shall return 0]
- result = RESULT_OK;
- }
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_043: [If `name` is not a supported option, `retry_control_set_option` shall fail and return non-zero]
- else
- {
- LogError("messenger_set_option failed (option with name '%s' is not suppported)", name);
- result = __FAILURE__;
- }
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, retry_control_set_option shall return 0]
+ result = RESULT_OK;
+ }
+ }
+ else if (strcmp(RETRY_CONTROL_OPTION_SAVED_OPTIONS, name) == 0)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_041: [If `name` is "retry_control_options", value shall be fed to `retry_control` using OptionHandler_FeedOptions]
+ if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, retry_control_handle) != OPTIONHANDLER_OK)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_042: [If OptionHandler_FeedOptions fails, `retry_control_set_option` shall fail and return non-zero]
+ LogError("messenger_set_option failed (OptionHandler_FeedOptions failed)");
+ result = __FAILURE__;
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_044: [If no errors occur, `retry_control_set_option` shall return 0]
+ result = RESULT_OK;
+ }
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_043: [If `name` is not a supported option, `retry_control_set_option` shall fail and return non-zero]
+ else
+ {
+ LogError("messenger_set_option failed (option with name '%s' is not suppported)", name);
+ result = __FAILURE__;
+ }
+ }
- return result;
+ return result;
}
OPTIONHANDLER_HANDLE retry_control_retrieve_options(RETRY_CONTROL_HANDLE retry_control_handle)
{
- OPTIONHANDLER_HANDLE result;
+ OPTIONHANDLER_HANDLE result;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_045: [If `retry_control_handle`, `retry_control_retrieve_options` shall fail and return NULL]
- if (retry_control_handle == NULL)
- {
- LogError("Failed to retrieve options (retry_state_handle is NULL)");
- result = NULL;
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_046: [An instance of OPTIONHANDLER_HANDLE (a.k.a. `options`) shall be created using OptionHandler_Create]
- OPTIONHANDLER_HANDLE options = OptionHandler_Create(retry_control_clone_option, retry_control_destroy_option, (pfSetOption)retry_control_set_option);
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_045: [If `retry_control_handle`, `retry_control_retrieve_options` shall fail and return NULL]
+ if (retry_control_handle == NULL)
+ {
+ LogError("Failed to retrieve options (retry_state_handle is NULL)");
+ result = NULL;
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_046: [An instance of OPTIONHANDLER_HANDLE (a.k.a. `options`) shall be created using OptionHandler_Create]
+ OPTIONHANDLER_HANDLE options = OptionHandler_Create(retry_control_clone_option, retry_control_destroy_option, (pfSetOption)retry_control_set_option);
- if (options == NULL)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_047: [If OptionHandler_Create fails, `retry_control_retrieve_options` shall fail and return NULL]
- LogError("Failed to retrieve options (OptionHandler_Create failed)");
- result = NULL;
- }
- else
- {
- RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
+ if (options == NULL)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_047: [If OptionHandler_Create fails, `retry_control_retrieve_options` shall fail and return NULL]
+ LogError("Failed to retrieve options (OptionHandler_Create failed)");
+ result = NULL;
+ }
+ else
+ {
+ RETRY_CONTROL_INSTANCE* retry_control = (RETRY_CONTROL_INSTANCE*)retry_control_handle;
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_050: [`retry_control->initial_wait_time_in_secs` shall be added to `options` using OptionHandler_Add]
- if (OptionHandler_AddOption(options, RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, (void*)&retry_control->initial_wait_time_in_secs) != OPTIONHANDLER_OK)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_052: [If any call to OptionHandler_Add fails, `retry_control_retrieve_options` shall fail and return NULL]
- LogError("Failed to retrieve options (OptionHandler_Create failed for option '%s')", RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS);
- result = NULL;
- }
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_051: [`retry_control->max_jitter_percent` shall be added to `options` using OptionHandler_Add]
- else if (OptionHandler_AddOption(options, RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, (void*)&retry_control->max_jitter_percent) != OPTIONHANDLER_OK)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_052: [If any call to OptionHandler_Add fails, `retry_control_retrieve_options` shall fail and return NULL]
- LogError("Failed to retrieve options (OptionHandler_Create failed for option '%s')", RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS);
- result = NULL;
- }
- else
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_054: [If no errors occur, `retry_control_retrieve_options` shall return the OPTIONHANDLER_HANDLE instance]
- result = options;
- }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_050: [`retry_control->initial_wait_time_in_secs` shall be added to `options` using OptionHandler_Add]
+ if (OptionHandler_AddOption(options, RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS, (void*)&retry_control->initial_wait_time_in_secs) != OPTIONHANDLER_OK)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_052: [If any call to OptionHandler_Add fails, `retry_control_retrieve_options` shall fail and return NULL]
+ LogError("Failed to retrieve options (OptionHandler_Create failed for option '%s')", RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS);
+ result = NULL;
+ }
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_051: [`retry_control->max_jitter_percent` shall be added to `options` using OptionHandler_Add]
+ else if (OptionHandler_AddOption(options, RETRY_CONTROL_OPTION_MAX_JITTER_PERCENT, (void*)&retry_control->max_jitter_percent) != OPTIONHANDLER_OK)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_052: [If any call to OptionHandler_Add fails, `retry_control_retrieve_options` shall fail and return NULL]
+ LogError("Failed to retrieve options (OptionHandler_Create failed for option '%s')", RETRY_CONTROL_OPTION_INITIAL_WAIT_TIME_IN_SECS);
+ result = NULL;
+ }
+ else
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_054: [If no errors occur, `retry_control_retrieve_options` shall return the OPTIONHANDLER_HANDLE instance]
+ result = options;
+ }
- if (result == NULL)
- {
- // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_053: [If any failures occur, `retry_control_retrieve_options` shall release any memory it has allocated]
- OptionHandler_Destroy(options);
- }
- }
- }
+ if (result == NULL)
+ {
+ // Codes_SRS_IOTHUB_CLIENT_RETRY_CONTROL_09_053: [If any failures occur, `retry_control_retrieve_options` shall release any memory it has allocated]
+ OptionHandler_Destroy(options);
+ }
+ }
+ }
- return result;
-}
\ No newline at end of file
+ return result;
+}
--- a/iothubtransport_mqtt_common.c Tue Jun 26 19:14:02 2018 -0700
+++ b/iothubtransport_mqtt_common.c Tue Sep 11 11:12:42 2018 -0700
@@ -11,6 +11,7 @@
#include "azure_c_shared_utility/doublylinkedlist.h"
#include "azure_c_shared_utility/crt_abstractions.h"
#include "azure_c_shared_utility/agenttime.h"
+#include "azure_c_shared_utility/threadapi.h"
#include "iothub_client_core_ll.h"
#include "iothub_client_options.h"
@@ -52,6 +53,7 @@
#define DEFAULT_RETRY_POLICY IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER
#define DEFAULT_RETRY_TIMEOUT_IN_SECONDS 0
+#define MAX_DISCONNECT_VALUE 50
static const char TOPIC_DEVICE_TWIN_PREFIX[] = "$iothub/twin";
static const char TOPIC_DEVICE_METHOD_PREFIX[] = "$iothub/methods";
@@ -165,6 +167,7 @@
STRING_HANDLE module_id;
STRING_HANDLE devicesAndModulesPath;
int portNum;
+ bool conn_attempted;
MQTT_GET_IO_TRANSPORT get_io_transport;
@@ -179,18 +182,20 @@
// Upper layer
IOTHUB_CLIENT_CORE_LL_HANDLE llClientHandle;
- // Protocol
+ // Protocol
MQTT_CLIENT_HANDLE mqttClient;
XIO_HANDLE xioTransport;
// Session - connection
uint16_t packetId;
+ uint16_t twin_resp_packet_id;
// Connection state control
bool isRegistered;
MQTT_CLIENT_STATUS mqttClientStatus;
bool isDestroyCalled;
bool device_twin_get_sent;
+ bool twin_resp_sub_recv;
bool isRecoverableError;
uint16_t keepAliveValue;
uint16_t connect_timeout_in_sec;
@@ -300,7 +305,7 @@
set_saved_tls_options(transport_data, NULL);
tickcounter_destroy(transport_data->msgTickCounter);
-
+
free_proxy_data(transport_data);
STRING_delete(transport_data->devicesAndModulesPath);
@@ -314,7 +319,7 @@
STRING_delete(transport_data->topic_NotifyState);
STRING_delete(transport_data->topic_DeviceMethods);
STRING_delete(transport_data->topic_InputQueue);
-
+
free(transport_data);
}
@@ -357,7 +362,7 @@
static uint16_t get_next_packet_id(PMQTTTRANSPORT_HANDLE_DATA transport_data)
{
- if (transport_data->packetId+1 >= USHRT_MAX)
+ if (transport_data->packetId + 1 >= USHRT_MAX)
{
transport_data->packetId = 1;
}
@@ -368,6 +373,7 @@
return transport_data->packetId;
}
+#ifndef NO_LOGGING
static const char* retrieve_mqtt_return_codes(CONNECT_RETURN_CODE rtn_code)
{
switch (rtn_code)
@@ -389,6 +395,7 @@
return "Unknown";
}
}
+#endif // NO_LOGGING
static int retrieve_device_method_rid_info(const char* resp_topic, STRING_HANDLE method_name, STRING_HANDLE request_id)
{
@@ -430,7 +437,7 @@
const char* request_id_value = STRING_c_str(token_value);
if (memcmp(request_id_value, REQUEST_ID_PROPERTY, request_id_length) == 0)
{
- if (STRING_concat(request_id, request_id_value+request_id_length) != 0)
+ if (STRING_concat(request_id, request_id_value + request_id_length) != 0)
{
LogError("Failed STRING_concat failed.");
result = __FAILURE__;
@@ -527,7 +534,7 @@
{
result = 0;
- while(n-- && result == 0)
+ while (n-- && result == 0)
{
if (*s1 == 0) result = -1;
else if (*s2 == 0) result = 1;
@@ -548,16 +555,16 @@
static IOTHUB_IDENTITY_TYPE retrieve_topic_type(const char* topic_resp, const char* input_queue)
{
IOTHUB_IDENTITY_TYPE type;
- if (InternStrnicmp(topic_resp, TOPIC_DEVICE_TWIN_PREFIX, sizeof(TOPIC_DEVICE_TWIN_PREFIX)-1) == 0)
+ if (InternStrnicmp(topic_resp, TOPIC_DEVICE_TWIN_PREFIX, sizeof(TOPIC_DEVICE_TWIN_PREFIX) - 1) == 0)
{
type = IOTHUB_TYPE_DEVICE_TWIN;
}
- else if (InternStrnicmp(topic_resp, TOPIC_DEVICE_METHOD_PREFIX, sizeof(TOPIC_DEVICE_METHOD_PREFIX)-1) == 0)
+ else if (InternStrnicmp(topic_resp, TOPIC_DEVICE_METHOD_PREFIX, sizeof(TOPIC_DEVICE_METHOD_PREFIX) - 1) == 0)
{
type = IOTHUB_TYPE_DEVICE_METHODS;
}
// input_queue contains additional "#" from subscribe, which we strip off on comparing incoming.
- else if ((input_queue != NULL) && InternStrnicmp(topic_resp, input_queue, strlen(input_queue)-1) == 0)
+ else if ((input_queue != NULL) && InternStrnicmp(topic_resp, input_queue, strlen(input_queue) - 1) == 0)
{
type = IOTHUB_TYPE_EVENT_QUEUE;
}
@@ -871,7 +878,7 @@
int result;
uint16_t packet_id = get_next_packet_id(transport_data);
- STRING_HANDLE msg_topic = STRING_construct_sprintf(DEVICE_METHOD_RESPONSE_TOPIC, status_code, STRING_c_str(request_id) );
+ STRING_HANDLE msg_topic = STRING_construct_sprintf(DEVICE_METHOD_RESPONSE_TOPIC, status_code, STRING_c_str(request_id));
if (msg_topic == NULL)
{
LogError("Failed constructing message topic.");
@@ -1005,10 +1012,53 @@
return result;
}
+static void changeStateToSubscribeIfAllowed(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+ if (transport_data->currPacketState != CONNACK_TYPE &&
+ transport_data->currPacketState != CONNECT_TYPE &&
+ transport_data->currPacketState != DISCONNECT_TYPE &&
+ transport_data->currPacketState != PACKET_TYPE_ERROR)
+ {
+ transport_data->currPacketState = SUBSCRIBE_TYPE;
+ }
+}
+
+static int subscribeToNotifyStateIfNeeded(PMQTTTRANSPORT_HANDLE_DATA transport_data)
+{
+ int result;
+
+ if (transport_data->topic_NotifyState == NULL)
+ {
+ transport_data->topic_NotifyState = STRING_construct(TOPIC_NOTIFICATION_STATE);
+ if (transport_data->topic_NotifyState == NULL)
+ {
+ LogError("Failure: unable constructing notify state topic");
+ result = __FAILURE__;
+ }
+ else
+ {
+ transport_data->topics_ToSubscribe |= SUBSCRIBE_NOTIFICATION_STATE_TOPIC;
+ result = 0;
+ }
+ }
+ else
+ {
+ result = 0;
+ }
+
+ if (result == 0)
+ {
+ changeStateToSubscribeIfAllowed(transport_data);
+ }
+
+ return result;
+}
+
+
static bool isSystemProperty(const char* tokenData)
{
bool result = false;
- size_t propCount = sizeof(sysPropList)/sizeof(sysPropList[0]);
+ size_t propCount = sizeof(sysPropList) / sizeof(sysPropList[0]);
size_t index = 0;
for (index = 0; index < propCount; index++)
{
@@ -1069,7 +1119,7 @@
result = __FAILURE__;
}
STRING_TOKENIZER_destroy(token_handle);
- }
+ }
return result;
}
@@ -1078,7 +1128,7 @@
{
// Not finding a system property to map to isn't an error.
int result = 0;
-
+
if (nameLen > 4)
{
if (strcmp((const char*)&propName[nameLen - 4], CONNECTION_DEVICE_ID) == 0)
@@ -1213,10 +1263,10 @@
}
else
{
- strncpy(propName, tokenData, nameLen);
+ memcpy(propName, tokenData, nameLen);
propName[nameLen] = '\0';
- strncpy(propValue, iterator + 1, valLen);
+ memcpy(propValue, iterator + 1, valLen);
propValue[valLen] = '\0';
if (urldecode)
@@ -1270,10 +1320,10 @@
}
else
{
- strncpy(propName, tokenData, nameLen);
+ memcpy(propName, tokenData, nameLen);
propName[nameLen] = '\0';
- strncpy(propValue, iterator + 1, valLen);
+ memcpy(propValue, iterator + 1, valLen);
propValue[valLen] = '\0';
if (urldecode)
@@ -1374,6 +1424,8 @@
{
/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_054: [ If type is IOTHUB_TYPE_DEVICE_TWIN, then on success if msg_type is RETRIEVE_PROPERTIES then mqtt_notification_callback shall call IoTHubClientCore_LL_RetrievePropertyComplete... ] */
IoTHubClientCore_LL_RetrievePropertyComplete(transportData->llClientHandle, DEVICE_TWIN_UPDATE_COMPLETE, payload->message, payload->length);
+ // Only after receiving device twin request should we start listening for patches.
+ (void)subscribeToNotifyStateIfNeeded(transportData);
}
else
{
@@ -1397,7 +1449,7 @@
}
else
{
- DEVICE_METHOD_INFO* dev_method_info = malloc(sizeof(DEVICE_METHOD_INFO) );
+ DEVICE_METHOD_INFO* dev_method_info = malloc(sizeof(DEVICE_METHOD_INFO));
if (dev_method_info == NULL)
{
LogError("Failure: allocating DEVICE_METHOD_INFO object");
@@ -1564,7 +1616,7 @@
{
transport_data->isRecoverableError = false;
}
- LogError("Connection Not Accepted: 0x%x: %s", connack->returnCode, retrieve_mqtt_return_codes(connack->returnCode) );
+ LogError("Connection Not Accepted: 0x%x: %s", connack->returnCode, retrieve_mqtt_return_codes(connack->returnCode));
transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_PENDING_CLOSE;
transport_data->currPacketState = PACKET_TYPE_ERROR;
}
@@ -1590,6 +1642,12 @@
}
// The connect packet has been acked
transport_data->currPacketState = SUBACK_TYPE;
+
+ // Is this a twin message
+ if (suback->packetId == transport_data->twin_resp_packet_id)
+ {
+ transport_data->twin_resp_sub_recv = true;
+ }
}
else
{
@@ -1615,17 +1673,17 @@
default:
{
break;
- }
+ }
}
}
}
-// Prior to creating a new connection, if we have an existing xioTransport we need to clear
-// it now or else cached settings (especially TLS when communicating with HTTP proxies) will
-// break reconnection attempt.
+// Prior to creating a new connection, if we have an existing xioTransport that has been connected before
+// we need to clear it now or else cached settings (especially TLS when communicating with HTTP proxies)
+// will break reconnection attempt.
static void ResetConnectionIfNecessary(PMQTTTRANSPORT_HANDLE_DATA transport_data)
{
- if (transport_data->xioTransport != NULL)
+ if (transport_data->xioTransport != NULL && transport_data->conn_attempted)
{
OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport);
set_saved_tls_options(transport_data, options);
@@ -1635,6 +1693,15 @@
}
}
+static void mqtt_disconnect_cb(void* ctx)
+{
+ if (ctx != NULL)
+ {
+ int* disconn_recv = (int*)ctx;
+ *disconn_recv = 1;
+ }
+}
+
static void DisconnectFromClient(PMQTTTRANSPORT_HANDLE_DATA transport_data)
{
if (!transport_data->isDestroyCalled)
@@ -1642,8 +1709,19 @@
OPTIONHANDLER_HANDLE options = xio_retrieveoptions(transport_data->xioTransport);
set_saved_tls_options(transport_data, options);
}
-
- (void)mqtt_client_disconnect(transport_data->mqttClient, NULL, NULL);
+ // Ensure the disconnect message is sent
+ if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_CONNECTED)
+ {
+ int disconn_recv = 0;
+ (void)mqtt_client_disconnect(transport_data->mqttClient, mqtt_disconnect_cb, &disconn_recv);
+ size_t disconnect_ctr = 0;
+ do
+ {
+ mqtt_client_dowork(transport_data->mqttClient);
+ disconnect_ctr++;
+ ThreadAPI_Sleep(50);
+ } while ((disconnect_ctr < MAX_DISCONNECT_VALUE) && (disconn_recv == 0));
+ }
xio_destroy(transport_data->xioTransport);
transport_data->xioTransport = NULL;
@@ -1677,7 +1755,7 @@
}
case MQTT_CLIENT_PARSE_ERROR:
case MQTT_CLIENT_MEMORY_ERROR:
- case MQTT_CLIENT_UNKNOWN_ERROR:
+ case MQTT_CLIENT_UNKNOWN_ERROR:
{
LogError("INTERNAL ERROR: unexpected error value received %s", ENUM_TO_STRING(MQTT_CLIENT_EVENT_ERROR, error));
break;
@@ -1722,6 +1800,7 @@
{
uint32_t topic_subscription = 0;
size_t subscribe_count = 0;
+ uint16_t packet_id = get_next_packet_id(transport_data);
SUBSCRIBE_PAYLOAD subscribe[SUBSCRIBE_TOPIC_COUNT];
if ((transport_data->topic_MqttMessage != NULL) && (SUBSCRIBE_TELEMETRY_TOPIC & transport_data->topics_ToSubscribe))
{
@@ -1736,6 +1815,7 @@
subscribe[subscribe_count].qosReturn = DELIVER_AT_MOST_ONCE;
topic_subscription |= SUBSCRIBE_GET_REPORTED_STATE_TOPIC;
subscribe_count++;
+ transport_data->twin_resp_packet_id = packet_id;
}
if ((transport_data->topic_NotifyState != NULL) && (SUBSCRIBE_NOTIFICATION_STATE_TOPIC & transport_data->topics_ToSubscribe))
{
@@ -1762,7 +1842,7 @@
if (subscribe_count != 0)
{
/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_016: [IoTHubTransport_MQTT_Common_Subscribe shall call mqtt_client_subscribe to subscribe to the Message Topic.] */
- if (mqtt_client_subscribe(transport_data->mqttClient, get_next_packet_id(transport_data), subscribe, subscribe_count) != 0)
+ if (mqtt_client_subscribe(transport_data->mqttClient, packet_id, subscribe, subscribe_count) != 0)
{
/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_017: [Upon failure IoTHubTransport_MQTT_Common_Subscribe shall return a non-zero value.] */
LogError("Failure: mqtt_client_subscribe returned error.");
@@ -1787,37 +1867,41 @@
}
}
-static const unsigned char* RetrieveMessagePayload(IOTHUB_MESSAGE_HANDLE messageHandle, size_t* length)
+static bool RetrieveMessagePayload(IOTHUB_MESSAGE_HANDLE messageHandle, const unsigned char** payload, size_t* length)
{
- const unsigned char* result;
-
+ bool result;
IOTHUBMESSAGE_CONTENT_TYPE contentType = IoTHubMessage_GetContentType(messageHandle);
if (contentType == IOTHUBMESSAGE_BYTEARRAY)
{
- if (IoTHubMessage_GetByteArray(messageHandle, &result, length) != IOTHUB_MESSAGE_OK)
+ if (IoTHubMessage_GetByteArray(messageHandle, &(*payload), length) != IOTHUB_MESSAGE_OK)
{
LogError("Failure result from IoTHubMessage_GetByteArray");
- result = NULL;
+ result = false;
*length = 0;
}
+ else
+ {
+ result = true;
+ }
}
else if (contentType == IOTHUBMESSAGE_STRING)
{
- result = (const unsigned char*)IoTHubMessage_GetString(messageHandle);
- if (result == NULL)
+ *payload = (const unsigned char*)IoTHubMessage_GetString(messageHandle);
+ if (*payload == NULL)
{
LogError("Failure result from IoTHubMessage_GetString");
- result = NULL;
+ result = false;
*length = 0;
}
else
{
- *length = strlen((const char*)result);
+ *length = strlen((const char*)*payload);
+ result = true;
}
}
else
{
- result = NULL;
+ result = false;
*length = 0;
}
return result;
@@ -1848,6 +1932,7 @@
}
else
{
+ transport_data->conn_attempted = true;
if (transport_data->saved_tls_options != NULL)
{
if (OptionHandler_FeedOptions(transport_data->saved_tls_options, transport_data->xioTransport) != OPTIONHANDLER_OK)
@@ -2047,7 +2132,7 @@
{
result = __FAILURE__;
}
-
+
if (sasToken != NULL)
{
free(sasToken);
@@ -2069,7 +2154,7 @@
RETRY_ACTION retry_action = RETRY_ACTION_RETRY_LATER;
// Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_09_007: [ IoTHubTransport_MQTT_Common_DoWork shall try to reconnect according to the current retry policy set ]
- if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_NOT_CONNECTED && transport_data->isRecoverableError &&
+ if (transport_data->mqttClientStatus == MQTT_CLIENT_STATUS_NOT_CONNECTED && transport_data->isRecoverableError &&
(retry_control_should_retry(transport_data->retry_control_handle, &retry_action) != 0 || retry_action == RETRY_ACTION_RETRY_NOW))
{
// Note: in case retry_control_should_retry fails, the reconnection shall be attempted anyway (defaulting to policy IOTHUB_CLIENT_RETRY_IMMEDIATE).
@@ -2126,14 +2211,9 @@
if ((current_time - transport_data->mqtt_connect_time) / 1000 > (transport_data->option_sas_token_lifetime_secs*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. ] */
- 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;
+ DisconnectFromClient(transport_data);
IoTHubClientCore_LL_ConnectionStatusCallBack(transport_data->llClientHandle, IOTHUB_CLIENT_CONNECTION_UNAUTHENTICATED, IOTHUB_CLIENT_CONNECTION_EXPIRED_SAS_TOKEN);
- transport_data->mqttClientStatus = MQTT_CLIENT_STATUS_NOT_CONNECTED;
transport_data->currPacketState = UNKNOWN_TYPE;
transport_data->device_twin_get_sent = false;
if (transport_data->topic_MqttMessage != NULL)
@@ -2208,7 +2288,7 @@
}
else
{
- memset(state, 0, sizeof(MQTTTRANSPORT_HANDLE_DATA) );
+ memset(state, 0, sizeof(MQTTTRANSPORT_HANDLE_DATA));
if ((state->msgTickCounter = tickcounter_create()) == NULL)
{
LogError("Invalid Argument: iotHubName is empty");
@@ -2242,7 +2322,7 @@
}
else
{
- if ( (state->topic_MqttEvent = buildMqttEventString(upperConfig->deviceId, moduleId) ) == NULL)
+ if ((state->topic_MqttEvent = buildMqttEventString(upperConfig->deviceId, moduleId)) == NULL)
{
LogError("Could not create topic_MqttEvent for MQTT");
free_transport_handle_data(state);
@@ -2262,13 +2342,13 @@
/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_008: [If the upperConfig contains a valid protocolGatewayHostName value the this shall be used for the hostname, otherwise the hostname shall be constructed using the iothubname and iothubSuffix.] */
if (upperConfig->protocolGatewayHostName == NULL)
{
- state->hostAddress = STRING_construct_sprintf("%s.%s", upperConfig->iotHubName, upperConfig->iotHubSuffix);
+ state->hostAddress = STRING_construct_sprintf("%s.%s", upperConfig->iotHubName, upperConfig->iotHubSuffix);
}
else
{
state->hostAddress = STRING_construct(upperConfig->protocolGatewayHostName);
}
-
+
if (state->hostAddress == NULL)
{
LogError("failure constructing host address.");
@@ -2312,6 +2392,7 @@
state->isProductInfoSet = false;
state->option_sas_token_lifetime_secs = SAS_TOKEN_DEFAULT_LIFETIME;
state->auto_url_encode_decode = false;
+ state->conn_attempted = false;
}
}
}
@@ -2342,12 +2423,12 @@
/* 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)) ||
- //is_key_validate(config) != 0 ||
- config->upperConfig->iotHubName == NULL ||
- config->upperConfig->iotHubSuffix == NULL)
+ config->upperConfig->protocol == NULL ||
+ config->upperConfig->deviceId == 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;
@@ -2359,7 +2440,7 @@
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) )
+ else if (((deviceIdSize = strlen(config->upperConfig->deviceId)) > 128U) || (deviceIdSize == 0))
{
LogError("Invalid Argument: DeviceId is of an invalid size");
result = NULL;
@@ -2463,31 +2544,9 @@
{
result = 0;
}
- if (result == 0 && transport_data->topic_NotifyState == NULL)
- {
- /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_044: [`IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin` shall construct the get state topic string and the notify state topic string.] */
- transport_data->topic_NotifyState = STRING_construct(TOPIC_NOTIFICATION_STATE);
- if (transport_data->topic_NotifyState == NULL)
- {
- LogError("Failure: unable constructing notify state topic");
- result = __FAILURE__;
- }
- else
- {
- /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_047: [On success IoTHubTransport_MQTT_Common_Subscribe_DeviceTwin shall return 0.] */
- transport_data->topics_ToSubscribe |= SUBSCRIBE_NOTIFICATION_STATE_TOPIC;
- result = 0;
- }
- }
if (result == 0)
{
- if (transport_data->currPacketState != CONNACK_TYPE &&
- transport_data->currPacketState != CONNECT_TYPE &&
- transport_data->currPacketState != DISCONNECT_TYPE &&
- transport_data->currPacketState != PACKET_TYPE_ERROR)
- {
- transport_data->currPacketState = SUBSCRIBE_TYPE;
- }
+ changeStateToSubscribeIfAllowed(transport_data);
}
}
return result;
@@ -2560,13 +2619,7 @@
{
/*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_005 : [IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall schedule the send of the subscription.]*/
/*Codes_SRS_IOTHUB_MQTT_TRANSPORT_12_007 : [On success IoTHubTransport_MQTT_Common_Subscribe_DeviceMethod shall return 0.]*/
- if (transport_data->currPacketState != CONNACK_TYPE &&
- transport_data->currPacketState != CONNECT_TYPE &&
- transport_data->currPacketState != DISCONNECT_TYPE &&
- transport_data->currPacketState != PACKET_TYPE_ERROR)
- {
- transport_data->currPacketState = SUBSCRIBE_TYPE;
- }
+ changeStateToSubscribeIfAllowed(transport_data);
}
}
return result;
@@ -2666,7 +2719,7 @@
else
{
/* Code_SRS_IOTHUB_MQTT_TRANSPORT_07_016: [IoTHubTransport_MQTT_Common_Subscribe shall set a flag to enable mqtt_client_subscribe to be called to subscribe to the Message Topic.] */
- transport_data->topic_MqttMessage = buildTopicMqttMessage(STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id) );
+ transport_data->topic_MqttMessage = buildTopicMqttMessage(STRING_c_str(transport_data->device_id), STRING_c_str(transport_data->module_id));
if (transport_data->topic_MqttMessage == NULL)
{
LogError("Failure constructing Message Topic");
@@ -2676,13 +2729,7 @@
{
transport_data->topics_ToSubscribe |= SUBSCRIBE_TELEMETRY_TOPIC;
/* Code_SRS_IOTHUB_MQTT_TRANSPORT_07_035: [If current packet state is not CONNACT, DISCONNECT_TYPE, or PACKET_TYPE_ERROR then IoTHubTransport_MQTT_Common_Subscribe shall set the packet state to SUBSCRIBE_TYPE.]*/
- if (transport_data->currPacketState != CONNACK_TYPE &&
- transport_data->currPacketState != CONNECT_TYPE &&
- transport_data->currPacketState != DISCONNECT_TYPE &&
- transport_data->currPacketState != PACKET_TYPE_ERROR)
- {
- transport_data->currPacketState = SUBSCRIBE_TYPE;
- }
+ changeStateToSubscribeIfAllowed(transport_data);
result = 0;
}
}
@@ -2727,7 +2774,8 @@
if (transport_data->currPacketState == PUBLISH_TYPE)
{
- if (item_type == IOTHUB_TYPE_DEVICE_TWIN)
+ // Ensure the reported property suback has been received
+ if (item_type == IOTHUB_TYPE_DEVICE_TWIN && transport_data->twin_resp_sub_recv)
{
MQTT_DEVICE_TWIN_ITEM* mqtt_info = (MQTT_DEVICE_TWIN_ITEM*)malloc(sizeof(MQTT_DEVICE_TWIN_ITEM));
if (mqtt_info == NULL)
@@ -2741,7 +2789,7 @@
mqtt_info->iothub_type = item_type;
mqtt_info->iothub_msg_id = iothub_item->device_twin->item_id;
mqtt_info->retryCount = 0;
-
+
/* Codes_SRS_IOTHUBCLIENT_LL_07_005: [ If successful IoTHubTransport_MQTT_Common_ProcessItem shall add mqtt info structure acknowledgement queue. ] */
DList_InsertTailList(&transport_data->ack_waiting_queue, &mqtt_info->entry);
@@ -2855,10 +2903,12 @@
else
{
size_t messageLength;
- const unsigned char* messagePayload = RetrieveMessagePayload(mqttMsgEntry->iotHubMessageEntry->messageHandle, &messageLength);
- if (messageLength == 0 || messagePayload == NULL)
+ const unsigned char* messagePayload = NULL;
+ if (!RetrieveMessagePayload(mqttMsgEntry->iotHubMessageEntry->messageHandle, &messagePayload, &messageLength))
{
LogError("Failure from creating Message IoTHubMessage_GetData");
+ (void)DList_RemoveEntryList(currentListEntry);
+ sendMsgComplete(mqttMsgEntry->iotHubMessageEntry, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);
}
else
{
@@ -2884,9 +2934,11 @@
/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_027: [IoTHubTransport_MQTT_Common_DoWork shall inspect the "waitingToSend" DLIST passed in config structure.] */
size_t messageLength;
- const unsigned char* messagePayload = RetrieveMessagePayload(iothubMsgList->messageHandle, &messageLength);
- if (messageLength == 0 || messagePayload == NULL)
+ const unsigned char* messagePayload = NULL;
+ if (!RetrieveMessagePayload(iothubMsgList->messageHandle, &messagePayload, &messageLength))
{
+ (void)(DList_RemoveEntryList(currentListEntry));
+ sendMsgComplete(iothubMsgList, transport_data, IOTHUB_CLIENT_CONFIRMATION_ERROR);
LogError("Failure result from IoTHubMessage_GetData");
}
else
@@ -3108,7 +3160,7 @@
else
{
/* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_039: [If the option parameter is set to "x509certificate" then the value shall be a const char of the certificate to be used for x509.] */
- if ( ((strcmp(OPTION_X509_CERT, option) == 0) || (strcmp(OPTION_X509_PRIVATE_KEY, option) == 0)) && (cred_type != IOTHUB_CREDENTIAL_TYPE_X509) )
+ if (((strcmp(OPTION_X509_CERT, option) == 0) || (strcmp(OPTION_X509_PRIVATE_KEY, option) == 0)) && (cred_type != IOTHUB_CREDENTIAL_TYPE_X509))
{
IoTHubClient_Auth_Set_x509_Type(transport_data->authorization_module, true);
}
@@ -3191,12 +3243,12 @@
LogError("IoTHubTransport_MQTT_Common_Register: deviceId does not match.");
result = NULL;
}
- else if (! check_module_ids_equal(STRING_c_str(transport_data->module_id), device->moduleId))
+ else if (!check_module_ids_equal(STRING_c_str(transport_data->module_id), device->moduleId))
{
LogError("IoTHubTransport_MQTT_Common_Register: moduleId does not match.");
result = NULL;
}
- else if (IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module) == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY &&
+ else if (IoTHubClient_Auth_Get_Credential_Type(transport_data->authorization_module) == IOTHUB_CREDENTIAL_TYPE_DEVICE_KEY &&
(strcmp(IoTHubClient_Auth_Get_DeviceKey(transport_data->authorization_module), device->deviceKey) != 0))
{
LogError("IoTHubTransport_MQTT_Common_Register: deviceKey does not match.");
@@ -3306,14 +3358,7 @@
{
// Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_067: [ IoTHubTransport_MQTT_Common_Subscribe_InputQueue shall set a flag to enable mqtt_client_subscribe to be called to subscribe to the input queue Message Topic.]
transport_data->topics_ToSubscribe |= SUBSCRIBE_INPUT_QUEUE_TOPIC;
- if (transport_data->currPacketState != CONNACK_TYPE &&
- transport_data->currPacketState != CONNECT_TYPE &&
- transport_data->currPacketState != DISCONNECT_TYPE &&
- transport_data->currPacketState != PACKET_TYPE_ERROR)
- {
- // Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_068: [ If current packet state is not CONNACK, DISCONNECT_TYPE, or PACKET_TYPE_ERROR then IoTHubTransport_MQTT_Common_Subscribe_InputQueue shall set the packet state to SUBSCRIBE_TYPE.]
- transport_data->currPacketState = SUBSCRIBE_TYPE;
- }
+ changeStateToSubscribeIfAllowed(transport_data);
// Codes_SRS_IOTHUB_TRANSPORT_MQTT_COMMON_31_070: [ On success IoTHubTransport_MQTT_Common_Subscribe_InputQueue shall return 0.]
result = 0;
}
--- a/iothubtransportmqtt.c Tue Jun 26 19:14:02 2018 -0700
+++ b/iothubtransportmqtt.c Tue Sep 11 11:12:42 2018 -0700
@@ -117,7 +117,7 @@
static int IoTHubTransportMqtt_SetRetryPolicy(TRANSPORT_LL_HANDLE handle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
{
- /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_25_012: [** IoTHubTransportMqtt_SetRetryPolicy shall call into the IoTHubMqttAbstract_SetRetryPolicy function. ] */
+ /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_25_012: [** IoTHubTransportMqtt_SetRetryPolicy shall call into the IoTHubMqttAbstract_SetRetryPolicy function. ] */
return IoTHubTransport_MQTT_Common_SetRetryPolicy(handle, retryPolicy, retryTimeoutLimitInSeconds);
}
@@ -164,7 +164,7 @@
}
-static TRANSPORT_PROVIDER myfunc =
+static TRANSPORT_PROVIDER myfunc =
{
IoTHubTransportMqtt_SendMessageDisposition, /*pfIotHubTransport_SendMessageDisposition IoTHubTransport_SendMessageDisposition;*/
IoTHubTransportMqtt_Subscribe_DeviceMethod, /*pfIoTHubTransport_Subscribe_DeviceMethod IoTHubTransport_Subscribe_DeviceMethod;*/
--- a/iothubtransportmqtt.h Tue Jun 26 19:14:02 2018 -0700
+++ b/iothubtransportmqtt.h Tue Sep 11 11:12:42 2018 -0700
@@ -10,7 +10,7 @@
extern "C"
{
#endif
- extern const TRANSPORT_PROVIDER* MQTT_Protocol(void);
+ extern const TRANSPORT_PROVIDER* MQTT_Protocol(void);
#ifdef __cplusplus
}
