Commit fc5faa1f authored by Jaehong Jo's avatar Jaehong Jo Committed by Uze Choi

Added status check logic before transmission

When a retransmission occurs in a bad network situation,
it can happen that the status is twisted.
So Added the stateus check logic.

Change-Id: Ie7d1a7446d578e024fb3e787b9f0de18cd64a76e
Signed-off-by: default avatarJaehong <jaehong.jo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/27507Tested-by: default avatarIoTivity Jenkins <jenkins-daemon@iotivity.org>
Reviewed-by: default avatarjaehyun Cho <jaehyun3.cho@samsung.com>
Reviewed-by: default avatarUze Choi <uzchoi@samsung.com>
parent 6beca090
......@@ -31,19 +31,18 @@ extern "C" {
#endif
/**
@brief Cloud Connection Status.
All status can be set exclusively except CLOUD_MANAGER_RE_CONNECTING
,which requires OR/AND bitwise operation
@brief Cloud connection status.
*/
typedef enum {
CLOUD_MANAGER_INITIALIZE = 0,
CLOUD_MANAGER_INITIALIZED = 0,
CLOUD_MANAGER_SIGNED_UP = 1 << 0,
CLOUD_MANAGER_SIGNED_IN = 1 << 1,
CLOUD_MANAGER_PUBLISHED = 1 << 2,
CLOUD_MANAGER_FINISH = 1 << 3,
CLOUD_MANAGER_FAIL = 1 << 4,
CLOUD_MANAGER_RE_CONNECTING = 1 << 5,
CLOUD_MANAGER_RESET = 1 << 6
CLOUD_MANAGER_DEV_PUBLISHED = 1 << 2,
CLOUD_MANAGER_RES_PUBLISHED = 1 << 3,
CLOUD_MANAGER_FINISHED = 1 << 4,
CLOUD_MANAGER_FAILED = 1 << 5,
CLOUD_MANAGER_RECONNECTING = 1 << 6,
CLOUD_MANAGER_RESETTING = 1 << 7
} st_cloud_manager_status_t;
/**
......
......@@ -60,7 +60,7 @@ OC_LIST(st_cloud_context_list);
OC_MEMB(st_cloud_context_s, st_cloud_context_t, MAX_CONTEXT_SIZE);
struct oc_memb st_rep_objects_pool = { sizeof(oc_rep_t), 0, 0, 0, 0 };
static bool cloud_start_process(st_cloud_context_t *context);
static void cloud_start_process(st_cloud_context_t *context);
static oc_event_callback_retval_t sign_up(void *data);
static oc_event_callback_retval_t sign_in(void *data);
static oc_event_callback_retval_t refresh_token(void *data);
......@@ -115,24 +115,48 @@ session_event_handler(const oc_endpoint_t *endpoint, oc_session_state_t state)
{
st_print_log("[ST_CM] session state (%s)\n",
(state) ? "DISCONNECTED" : "CONNECTED");
if (state == OC_SESSION_CONNECTED)
return;
st_cloud_context_t *context = oc_list_head(st_cloud_context_list);
while (context != NULL && context->device_index != endpoint->device) {
context = context->next;
}
if (!context || context->cloud_manager_status & CLOUD_MANAGER_RE_CONNECTING ||
if (!context || context->cloud_manager_status == CLOUD_MANAGER_RECONNECTING ||
0 != oc_endpoint_compare(endpoint, &context->cloud_ep))
return;
if (state == OC_SESSION_DISCONNECTED) {
if (context->cloud_manager_status == CLOUD_MANAGER_FINISH) {
oc_remove_delayed_callback(context, send_ping);
oc_set_delayed_callback(context, callback_handler, 0);
}
context->cloud_manager_status |= CLOUD_MANAGER_RE_CONNECTING;
cloud_start_process(context);
switch (context->cloud_manager_status) {
case CLOUD_MANAGER_INITIALIZED:
oc_remove_delayed_callback(context, sign_up);
break;
case CLOUD_MANAGER_SIGNED_UP:
oc_remove_delayed_callback(context, sign_in);
break;
case CLOUD_MANAGER_SIGNED_IN: {
st_store_t *store_info = st_store_get_info();
if (store_info->cloudinfo.status != CLOUD_MANAGER_RES_PUBLISHED)
oc_remove_delayed_callback(context, set_dev_profile);
else
oc_remove_delayed_callback(context, find_ping);
} break;
case CLOUD_MANAGER_DEV_PUBLISHED:
oc_remove_delayed_callback(context, publish_resource);
break;
case CLOUD_MANAGER_RES_PUBLISHED:
oc_remove_delayed_callback(context, find_ping);
break;
case CLOUD_MANAGER_FINISHED:
oc_remove_delayed_callback(context, send_ping);
break;
default:
return;
}
context->cloud_manager_status = CLOUD_MANAGER_RECONNECTING;
oc_set_delayed_callback(context, callback_handler, 0);
cloud_start_process(context);
}
#endif /* OC_SESSION_EVENTS */
......@@ -153,10 +177,10 @@ st_cloud_manager_start(st_store_t *store_info, size_t device_index,
context->device_index = device_index;
context->cloud_manager_status =
(st_cloud_manager_status_t)store_info->cloudinfo.status;
if (context->cloud_manager_status == CLOUD_MANAGER_RES_PUBLISHED)
context->cloud_manager_status = CLOUD_MANAGER_SIGNED_UP;
cloud_start_process(context);
if (!cloud_start_process(context)) {
goto errors;
}
#ifdef OC_SESSION_EVENTS
if (oc_list_length(st_cloud_context_list) == 0) {
oc_add_session_event_callback(session_event_handler);
......@@ -165,11 +189,6 @@ st_cloud_manager_start(st_store_t *store_info, size_t device_index,
oc_list_add(st_cloud_context_list, context);
st_print_log("[ST_CM] st_cloud_manager_start success\n");
return 0;
errors:
es_set_state(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD);
oc_memb_free(&st_cloud_context_s, context);
return -1;
}
void
......@@ -186,7 +205,7 @@ st_cloud_manager_stop(size_t device_index)
return;
}
if (context->cloud_manager_status == CLOUD_MANAGER_FINISH)
if (context->cloud_manager_status == CLOUD_MANAGER_FINISHED)
oc_remove_delayed_callback(context, send_ping);
oc_list_remove(st_cloud_context_list, context);
......@@ -216,11 +235,13 @@ is_retry_over(st_cloud_context_t *context)
if (context->retry_count < MAX_RETRY_COUNT)
return false;
if (context->cloud_manager_status != CLOUD_MANAGER_RECONNECTING) {
context->cloud_manager_status = CLOUD_MANAGER_RECONNECTING;
oc_set_delayed_callback(context, callback_handler, 0);
}
#ifdef OC_TCP
oc_connectivity_end_session(&context->cloud_ep);
#endif /* OC_TCP */
context->retry_count = 0;
context->cloud_manager_status |= CLOUD_MANAGER_RE_CONNECTING;
cloud_start_process(context);
return true;
}
......@@ -269,15 +290,16 @@ error_handler(st_cloud_context_t *context, oc_rep_t* res_payload,
switch (code) {
case CI_TOKEN_EXPIRED:
oc_remove_delayed_callback(context, callback);
if (!(context->cloud_manager_status & CLOUD_MANAGER_RE_CONNECTING))
if (context->cloud_manager_status != CLOUD_MANAGER_RECONNECTING) {
context->retry_count = 0;
context->cloud_manager_status |= CLOUD_MANAGER_RE_CONNECTING;
context->cloud_manager_status = CLOUD_MANAGER_RECONNECTING;
}
oc_set_delayed_callback(context, refresh_token,
session_timeout[context->retry_count]);
break;
case CI_DEVICE_NOT_FOUND:
oc_remove_delayed_callback(context, callback);
context->cloud_manager_status = CLOUD_MANAGER_RESET;
context->cloud_manager_status = CLOUD_MANAGER_RESETTING;
oc_set_delayed_callback(context, callback_handler, 0);
break;
case CI_AUTHORIZATION_FAILED:
......@@ -285,30 +307,29 @@ error_handler(st_cloud_context_t *context, oc_rep_t* res_payload,
case CI_UNAUTHORIZED_TOKEN:
case CI_FORBIDDEN:
oc_remove_delayed_callback(context, callback);
context->cloud_manager_status = CLOUD_MANAGER_FAIL;
context->cloud_manager_status = CLOUD_MANAGER_FAILED;
es_set_state(ES_STATE_FAILED_TO_REGISTER_TO_CLOUD);
oc_set_delayed_callback(context, callback_handler, 0);
break;
case CI_INTERNAL_SERVER_ERROR:
default:
context->cloud_manager_status |= CLOUD_MANAGER_RE_CONNECTING;
break;
}
}
static bool
static void
cloud_start_process(st_cloud_context_t *context)
{
es_set_state(ES_STATE_REGISTERING_TO_CLOUD);
context->retry_count = 0;
if (context->cloud_manager_status == CLOUD_MANAGER_INITIALIZE) {
st_store_t *store_info = st_store_get_info();
if (store_info->cloudinfo.status == CLOUD_MANAGER_INITIALIZED) {
oc_set_delayed_callback(context, sign_up, session_timeout[0]);
} else {
oc_set_delayed_callback(context, sign_in, session_timeout[0]);
}
_oc_signal_event_loop();
return true;
}
static void
......@@ -319,6 +340,9 @@ sign_up_handler(oc_client_response_t *data)
oc_rep_t *payload = get_res_payload(data);
if (context->cloud_manager_status != CLOUD_MANAGER_INITIALIZED &&
context->cloud_manager_status != CLOUD_MANAGER_RECONNECTING)
return;
if (data->code != OC_STATUS_CHANGED)
goto error;
......@@ -360,16 +384,19 @@ sign_up(void *data)
st_cloud_context_t *context = (st_cloud_context_t *)data;
st_print_log("[ST_CM] try sign up(%d)\n", context->retry_count++);
if (!is_retry_over(context)) {
st_cloud_store_t cloudinfo = st_store_get_info()->cloudinfo;
if (0 ==
oc_string_to_endpoint(&cloudinfo.ci_server, &context->cloud_ep, NULL)) {
oc_sign_up(&context->cloud_ep, oc_string(cloudinfo.auth_provider),
oc_string(cloudinfo.uid), oc_string(cloudinfo.access_token),
context->device_index, sign_up_handler, context);
if (context->cloud_manager_status == CLOUD_MANAGER_INITIALIZED ||
context->cloud_manager_status == CLOUD_MANAGER_RECONNECTING) {
if (!is_retry_over(context)) {
st_cloud_store_t cloudinfo = st_store_get_info()->cloudinfo;
if (0 == oc_string_to_endpoint(&cloudinfo.ci_server, &context->cloud_ep,
NULL)) {
oc_sign_up(&context->cloud_ep, oc_string(cloudinfo.auth_provider),
oc_string(cloudinfo.uid), oc_string(cloudinfo.access_token),
context->device_index, sign_up_handler, context);
}
oc_set_delayed_callback(context, sign_up,
session_timeout[context->retry_count]);
}
oc_set_delayed_callback(context, sign_up,
session_timeout[context->retry_count]);
}
return OC_EVENT_DONE;
......@@ -382,15 +409,18 @@ sign_in_handler(oc_client_response_t *data)
oc_rep_t *payload = NULL;
st_print_log("[ST_CM] sign in handler(%d)\n", data->code);
if (context->cloud_manager_status != CLOUD_MANAGER_SIGNED_UP &&
context->cloud_manager_status != CLOUD_MANAGER_RECONNECTING)
return;
if (data->code != OC_STATUS_CHANGED)
goto error;
oc_remove_delayed_callback(context, sign_in);
context->retry_count = 0;
context->cloud_manager_status &= ~CLOUD_MANAGER_RE_CONNECTING;
context->cloud_manager_status = CLOUD_MANAGER_SIGNED_IN;
if (context->cloud_manager_status == CLOUD_MANAGER_SIGNED_UP ||
context->cloud_manager_status == CLOUD_MANAGER_SIGNED_IN) {
st_store_t *store_info = st_store_get_info();
if (store_info->cloudinfo.status != CLOUD_MANAGER_RES_PUBLISHED) {
es_set_state(ES_STATE_PUBLISHING_RESOURCES_TO_CLOUD);
oc_set_delayed_callback(context, set_dev_profile,
message_timeout[context->retry_count]);
......@@ -399,7 +429,6 @@ sign_in_handler(oc_client_response_t *data)
oc_set_delayed_callback(context, find_ping,
message_timeout[context->retry_count]);
}
context->cloud_manager_status = CLOUD_MANAGER_SIGNED_IN;
return;
error:
......@@ -414,16 +443,19 @@ sign_in(void *data)
st_cloud_context_t *context = (st_cloud_context_t *)data;
st_print_log("[ST_CM] try sign in(%d)\n", context->retry_count++);
if (!is_retry_over(context)) {
st_cloud_store_t cloudinfo = st_store_get_info()->cloudinfo;
if (0 ==
oc_string_to_endpoint(&cloudinfo.ci_server, &context->cloud_ep, NULL)) {
oc_sign_in(&context->cloud_ep, oc_string(cloudinfo.uid),
oc_string(cloudinfo.access_token), 0, sign_in_handler,
context);
if (context->cloud_manager_status == CLOUD_MANAGER_SIGNED_UP ||
context->cloud_manager_status == CLOUD_MANAGER_RECONNECTING) {
if (!is_retry_over(context)) {
st_cloud_store_t cloudinfo = st_store_get_info()->cloudinfo;
if (0 == oc_string_to_endpoint(&cloudinfo.ci_server, &context->cloud_ep,
NULL)) {
oc_sign_in(&context->cloud_ep, oc_string(cloudinfo.uid),
oc_string(cloudinfo.access_token), 0, sign_in_handler,
context);
}
oc_set_delayed_callback(context, sign_in,
session_timeout[context->retry_count]);
}
oc_set_delayed_callback(context, sign_in,
session_timeout[context->retry_count]);
}
return OC_EVENT_DONE;
......@@ -497,11 +529,14 @@ set_dev_profile_handler(oc_client_response_t *data)
oc_rep_t *payload = NULL;
st_print_log("[ST_CM] set dev profile handler(%d)\n", data->code);
if (context->cloud_manager_status != CLOUD_MANAGER_SIGNED_IN)
return;
if (data->code != OC_STATUS_CHANGED)
goto error;
oc_remove_delayed_callback(context, set_dev_profile);
context->retry_count = 0;
context->cloud_manager_status = CLOUD_MANAGER_DEV_PUBLISHED;
oc_set_delayed_callback(context, publish_resource,
message_timeout[context->retry_count]);
return;
......@@ -518,10 +553,13 @@ set_dev_profile(void *data)
st_cloud_context_t *context = (st_cloud_context_t *)data;
st_print_log("[ST_CM] try set dev profile(%d)\n", context->retry_count++);
if (!is_retry_over(context)) {
oc_set_device_profile(&context->cloud_ep, set_dev_profile_handler, context);
oc_set_delayed_callback(context, set_dev_profile,
message_timeout[context->retry_count]);
if (context->cloud_manager_status == CLOUD_MANAGER_SIGNED_IN) {
if (!is_retry_over(context)) {
oc_set_device_profile(&context->cloud_ep, set_dev_profile_handler,
context);
oc_set_delayed_callback(context, set_dev_profile,
message_timeout[context->retry_count]);
}
}
return OC_EVENT_DONE;
......@@ -534,18 +572,20 @@ publish_resource_handler(oc_client_response_t *data)
oc_rep_t *payload = NULL;
st_print_log("[ST_CM] publish resource handler(%d)\n", data->code);
if (context->cloud_manager_status != CLOUD_MANAGER_DEV_PUBLISHED)
return;
if (data->code != OC_STATUS_CHANGED)
goto error;
oc_remove_delayed_callback(context, publish_resource);
context->retry_count = 0;
context->cloud_manager_status = CLOUD_MANAGER_PUBLISHED;
context->cloud_manager_status = CLOUD_MANAGER_RES_PUBLISHED;
es_set_state(ES_STATE_PUBLISHED_RESOURCES_TO_CLOUD);
oc_set_delayed_callback(context, find_ping,
message_timeout[context->retry_count]);
st_store_t *store_info = st_store_get_info();
store_info->cloudinfo.status = CLOUD_MANAGER_PUBLISHED;
store_info->cloudinfo.status = CLOUD_MANAGER_RES_PUBLISHED;
st_store_dump_async();
return;
......@@ -561,11 +601,13 @@ publish_resource(void *data)
st_cloud_context_t *context = (st_cloud_context_t *)data;
st_print_log("[ST_CM] try publish resource(%d)\n", context->retry_count++);
if (!is_retry_over(context)) {
rd_publish_all(&context->cloud_ep, context->device_index,
publish_resource_handler, LOW_QOS, context);
oc_set_delayed_callback(context, publish_resource,
message_timeout[context->retry_count]);
if (context->cloud_manager_status == CLOUD_MANAGER_DEV_PUBLISHED) {
if (!is_retry_over(context)) {
rd_publish_all(&context->cloud_ep, context->device_index,
publish_resource_handler, LOW_QOS, context);
oc_set_delayed_callback(context, publish_resource,
message_timeout[context->retry_count]);
}
}
return OC_EVENT_DONE;
......@@ -579,14 +621,15 @@ find_ping_handler(oc_client_response_t *data)
oc_rep_t *payload = get_res_payload(data);
if (context->cloud_manager_status != CLOUD_MANAGER_SIGNED_IN &&
context->cloud_manager_status != CLOUD_MANAGER_RES_PUBLISHED)
return;
if (data->code != OC_STATUS_OK)
goto error;
oc_remove_delayed_callback(context, find_ping);
if (context->cloud_manager_status == CLOUD_MANAGER_FINISH)
goto exit;
context->retry_count = 0;
context->cloud_manager_status = CLOUD_MANAGER_FINISH;
context->cloud_manager_status = CLOUD_MANAGER_FINISHED;
int *interval = NULL;
size_t size;
......@@ -596,8 +639,6 @@ find_ping_handler(oc_client_response_t *data)
oc_set_delayed_callback(context, callback_handler, 0);
oc_set_delayed_callback(context, send_ping,
message_timeout[context->retry_count]);
exit:
free_res_payload(payload);
return;
......@@ -612,9 +653,9 @@ find_ping(void *data)
st_cloud_context_t *context = (st_cloud_context_t *)data;
st_print_log("[ST_CM] try find ping(%d)\n", context->retry_count++);
if (!is_retry_over(context)) {
if (context->cloud_manager_status == CLOUD_MANAGER_SIGNED_IN ||
context->cloud_manager_status == CLOUD_MANAGER_PUBLISHED) {
if (context->cloud_manager_status == CLOUD_MANAGER_SIGNED_IN ||
context->cloud_manager_status == CLOUD_MANAGER_RES_PUBLISHED) {
if (!is_retry_over(context)) {
oc_find_ping_resource(&context->cloud_ep, find_ping_handler, context);
oc_set_delayed_callback(context, find_ping,
message_timeout[context->retry_count]);
......@@ -631,6 +672,8 @@ send_ping_handler(oc_client_response_t *data)
oc_rep_t *payload = NULL;
st_print_log("[ST_CM] send ping handler(%d)\n", data->code);
if (context->cloud_manager_status != CLOUD_MANAGER_FINISHED)
return;
if (data->code != OC_STATUS_NOT_MODIFIED)
goto error;
......@@ -651,8 +694,8 @@ send_ping(void *data)
st_cloud_context_t *context = (st_cloud_context_t *)data;
st_print_log("[ST_CM] try send ping(%d)\n", context->retry_count++);
if (!is_retry_over(context)) {
if (context->cloud_manager_status == CLOUD_MANAGER_FINISH) {
if (context->cloud_manager_status == CLOUD_MANAGER_FINISHED) {
if (!is_retry_over(context)) {
oc_send_ping_request(&context->cloud_ep, g_ping_interval,
send_ping_handler, context);
oc_set_delayed_callback(context, send_ping,
......
......@@ -266,18 +266,18 @@ easy_setup_handler(st_easy_setup_status_t status)
void
cloud_manager_handler(st_cloud_manager_status_t status)
{
if (status == CLOUD_MANAGER_FINISH) {
if (status == CLOUD_MANAGER_FINISHED) {
st_print_log("[ST_MGR] Cloud manager succeed!!!\n");
set_st_manager_status(ST_STATUS_DONE);
} else if (status == CLOUD_MANAGER_FAIL) {
} else if (status == CLOUD_MANAGER_FAILED) {
st_print_log("[ST_MGR] Cloud manager failed!!!\n");
g_start_fail = true;
set_st_manager_status(ST_STATUS_STOP);
} else if (status == CLOUD_MANAGER_RE_CONNECTING) {
st_print_log("[ST_MGR] Cloud manager re connecting!!!\n");
} else if (status == CLOUD_MANAGER_RECONNECTING) {
st_print_log("[ST_MGR] Cloud manager reconnecting!!!\n");
set_st_manager_status(ST_STATUS_CLOUD_MANAGER_RE_CONNECTING);
} else if (status == CLOUD_MANAGER_RESET) {
st_print_log("[ST_MGR] Cloud manager reset!!!\n");
} else if (status == CLOUD_MANAGER_RESETTING) {
st_print_log("[ST_MGR] Cloud manager resetting!!!\n");
set_st_manager_status(ST_STATUS_RESET);
}
}
......@@ -1150,17 +1150,17 @@ state_easy_setup_handler(st_easy_setup_status_t status)
void
state_cloud_manager_handler(st_cloud_manager_status_t status)
{
if (status == CLOUD_MANAGER_FINISH) {
if (status == CLOUD_MANAGER_FINISHED) {
st_print_log("[ST_MGR] Cloud manager succeed!!!\n");
st_manager_evt_with_signal(ST_EVT_RUN);
} else if (status == CLOUD_MANAGER_FAIL) {
} else if (status == CLOUD_MANAGER_FAILED) {
st_print_log("[ST_MGR] Cloud manager failed!!!\n");
st_manager_evt_with_signal(ST_EVT_STOP);
} else if (status == CLOUD_MANAGER_RE_CONNECTING) {
st_print_log("[ST_MGR] Cloud manager re connecting!!!\n");
} else if (status == CLOUD_MANAGER_RECONNECTING) {
st_print_log("[ST_MGR] Cloud manager reconnecting!!!\n");
// nothing.. just waiting
} else if (status == CLOUD_MANAGER_RESET) {
st_print_log("[ST_MGR] Cloud manager reset!!!\n");
} else if (status == CLOUD_MANAGER_RESETTING) {
st_print_log("[ST_MGR] Cloud manager resetting!!!\n");
st_manager_evt_with_signal(ST_EVT_RESET);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment