From: Jeongmo Yang Date: Fri, 4 Nov 2016 10:38:08 +0000 (+0900) Subject: Update code for message handling X-Git-Tag: accepted/tizen/common/20161109.140257^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fcec922cdacc89c7d46bc116f4b2812ace1f020a;p=platform%2Fcore%2Fapi%2Frecorder.git Update code for message handling 1. Process all received messages (Remove the code to drop message) 2. Add error handling for uncompleted message [Version] 0.2.44 [Profile] Common [Issue Type] Update [Dependency module] N/A [Test] [M(T/E) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-mobile_20161101.3] Change-Id: I6f9a0b2135460e6a42fc47f97b7a3f4ae1639d6c Signed-off-by: Jeongmo Yang --- diff --git a/include/recorder_private.h b/include/recorder_private.h index a214032..cc12f8e 100644 --- a/include/recorder_private.h +++ b/include/recorder_private.h @@ -26,7 +26,6 @@ extern "C" { #endif -#define RECORDER_PARSED_STRING_NUM_MAX 20 #define RECORDER_CB_TIMEOUT 5 #define RECORDER_FILENAME_MAX 256 @@ -82,7 +81,7 @@ typedef struct _recorder_cb_info_s { /* message receive thread */ GThread *msg_recv_thread; gint msg_recv_running; - gchar recv_msg[MUSE_RECORDER_MSG_MAX_LENGTH * RECORDER_PARSED_STRING_NUM_MAX]; + gchar recv_msg[MUSE_MSG_MAX_LENGTH]; GCond api_cond[MUSE_RECORDER_API_MAX]; GMutex api_mutex[MUSE_RECORDER_API_MAX]; gint api_activating[MUSE_RECORDER_API_MAX]; diff --git a/packaging/capi-media-recorder.spec b/packaging/capi-media-recorder.spec index 135d9c6..2eeae66 100644 --- a/packaging/capi-media-recorder.spec +++ b/packaging/capi-media-recorder.spec @@ -1,6 +1,6 @@ Name: capi-media-recorder Summary: A Recorder API -Version: 0.2.43 +Version: 0.2.44 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/recorder.c b/src/recorder.c index e4b0ffa..59689e6 100644 --- a/src/recorder.c +++ b/src/recorder.c @@ -510,129 +510,7 @@ static void __recorder_add_msg_to_queue(recorder_cb_info_s *cb_info, int api, in } -static void *_recorder_msg_handler_func(gpointer data) -{ - int api = 0; - int type = 0; - recorder_message_s *rec_msg = NULL; - recorder_idle_event_s *rec_idle_event = NULL; - recorder_msg_handler_info_s *handler_info = (recorder_msg_handler_info_s *)data; - recorder_cb_info_s *cb_info = NULL; - - if (!handler_info || !handler_info->cb_info) { - LOGE("NULL handler %p", handler_info); - return NULL; - } - - cb_info = (recorder_cb_info_s *)handler_info->cb_info; - type = handler_info->type; - - LOGD("t:%d start", type); - - g_mutex_lock(&handler_info->mutex); - - while (g_atomic_int_get(&handler_info->running)) { - if (g_queue_is_empty(handler_info->queue)) { - /*LOGD("signal wait...");*/ - g_cond_wait(&handler_info->cond, &handler_info->mutex); - /*LOGD("signal received");*/ - - if (g_atomic_int_get(&handler_info->running) == 0) { - LOGD("stop event thread"); - break; - } - } - - rec_msg = (recorder_message_s *)g_queue_pop_head(handler_info->queue); - g_mutex_unlock(&handler_info->mutex); - if (rec_msg == NULL) { - LOGE("NULL message"); - g_mutex_lock(&handler_info->mutex); - continue; - } - - api = rec_msg->api; - - if (api < MUSE_RECORDER_API_MAX) { - int ret = 0; - - g_mutex_lock(&cb_info->api_mutex[api]); - - if (muse_recorder_msg_get(ret, rec_msg->recv_msg)) { - cb_info->api_ret[api] = ret; - cb_info->api_activating[api] = 1; - - /*LOGD("recorder api %d - return 0x%x", ret);*/ - - g_cond_signal(&cb_info->api_cond[api]); - } else { - LOGE("t:%d failed to get ret for api %d, msg %s", type, api, rec_msg->recv_msg); - } - - g_mutex_unlock(&cb_info->api_mutex[api]); - } else if (api == MUSE_RECORDER_CB_EVENT) { - switch (rec_msg->event_class) { - case MUSE_RECORDER_EVENT_CLASS_THREAD_SUB: - _recorder_client_user_callback(cb_info, rec_msg->recv_msg, rec_msg->event); - break; - case MUSE_RECORDER_EVENT_CLASS_THREAD_MAIN: - rec_idle_event = g_new0(recorder_idle_event_s, 1); - if (rec_idle_event == NULL) { - LOGE("event alloc failed"); - break; - } - - rec_idle_event->event = rec_msg->event; - rec_idle_event->cb_info = cb_info; - g_mutex_init(&rec_idle_event->event_mutex); - strncpy(rec_idle_event->recv_msg, rec_msg->recv_msg, sizeof(rec_idle_event->recv_msg) - 1); - - /*LOGD("add recorder event[%d, %p] to IDLE", rec_msg->event, rec_idle_event);*/ - - g_mutex_lock(&cb_info->idle_event_mutex); - cb_info->idle_event_list = g_list_append(cb_info->idle_event_list, (gpointer)rec_idle_event); - g_mutex_unlock(&cb_info->idle_event_mutex); - - g_idle_add_full(G_PRIORITY_DEFAULT, - (GSourceFunc)_recorder_idle_event_callback, - (gpointer)rec_idle_event, - NULL); - break; - default: - LOGE("unknown event class %d", rec_msg->event_class); - break; - } - } else { - LOGE("unknown api[%d] message", api); - } - - g_free(rec_msg); - rec_msg = NULL; - - g_mutex_lock(&handler_info->mutex); - } - - /* remove remained event */ - while (!g_queue_is_empty(handler_info->queue)) { - rec_msg = (recorder_message_s *)g_queue_pop_head(handler_info->queue); - if (rec_msg) { - LOGD("remove message %p", rec_msg); - free(rec_msg); - rec_msg = NULL; - } else { - LOGW("NULL message"); - } - } - - g_mutex_unlock(&handler_info->mutex); - - LOGD("return"); - - return NULL; -} - - -static void _recorder_get_api_operation(int api, recorder_cb_info_s *cb_info, char *msg) +static void __recorder_get_api_operation(int api, recorder_cb_info_s *cb_info, char *msg) { if (!cb_info || !msg) { LOGE("NULL pointer %p %p", cb_info, msg); @@ -767,163 +645,313 @@ static void _recorder_get_api_operation(int api, recorder_cb_info_s *cb_info, ch } -static void *_recorder_msg_recv_func(gpointer data) +static void __recorder_process_msg(recorder_cb_info_s *cb_info, char *msg) { - int i = 0; - int ret = 0; - int api = 0; - int api_class = 0; - int event = 0; - int event_class = 0; - int num_token = 0; - int str_pos = 0; - int prev_pos = 0; - int msg_length = 0; - char *recv_msg = NULL; - char *error_msg = NULL; - char **parse_str = NULL; - recorder_cb_info_s *cb_info = (recorder_cb_info_s *)data; + int ret = RECORDER_ERROR_NONE; + int api = -1; + int api_class = -1; + int event = -1; + int event_class = -1; - if (cb_info == NULL) { - LOGE("cb_info NULL"); - return NULL; + if (!cb_info || !msg) { + LOGE("invalid ptr %p %p", cb_info, msg); + return; } - LOGD("start"); + /*LOGD("msg [%s]", msg);*/ - parse_str = (char **)malloc(sizeof(char *) * RECORDER_PARSED_STRING_NUM_MAX); - if (parse_str == NULL) { - LOGE("parse_str malloc failed"); - return NULL; + if (!muse_recorder_msg_get(api, msg)) { + LOGE("failed to get recorder api"); + return; } - for (i = 0 ; i < RECORDER_PARSED_STRING_NUM_MAX ; i++) { - parse_str[i] = (char *)malloc(sizeof(char) * MUSE_RECORDER_MSG_MAX_LENGTH); - if (parse_str[i] == NULL) { - LOGE("parse_str[%d] malloc failed", i); - goto CB_HANDLER_EXIT; + if (api == MUSE_RECORDER_CB_EVENT) { + if (!muse_recorder_msg_get(event, msg) || + !muse_recorder_msg_get(event_class, msg)) { + LOGE("failed to get event or event_class [%s]", msg); + return; + } + } else { + if (!muse_recorder_msg_get(api_class, msg)) { + LOGE("failed to get api_class [%s]", msg); + return; } } - recv_msg = cb_info->recv_msg; - - while (g_atomic_int_get(&cb_info->msg_recv_running)) { - ret = muse_core_ipc_recv_msg(cb_info->fd, recv_msg); - if (ret <= 0) { - cb_info->is_server_connected = FALSE; - LOGE("receive msg failed - server disconnected"); - break; + if (api_class == MUSE_RECORDER_API_CLASS_IMMEDIATE) { + if (api >= MUSE_RECORDER_API_MAX) { + LOGE("invalid api %d", api); + return; } - recv_msg[ret] = '\0'; - - str_pos = 0; - prev_pos = 0; - num_token = 0; + if (!muse_recorder_msg_get(ret, msg)) { + LOGE("failed to get recorder ret"); + return; + } - /*LOGD("recvMSg : %s, length : %d", recv_msg, ret);*/ + g_mutex_lock(&cb_info->api_mutex[api]); - /* Need to split the combined entering msgs. - This module supports up to 20 combined msgs. */ - for (str_pos = 0; str_pos < ret; str_pos++) { - if (recv_msg[str_pos] == '}') { - msg_length = str_pos - prev_pos + 1; + cb_info->api_ret[api] = ret; + cb_info->api_activating[api] = 1; - if (msg_length < MUSE_RECORDER_MSG_MAX_LENGTH) { - strncpy(parse_str[num_token], recv_msg + prev_pos, msg_length); - parse_str[num_token][msg_length] = '\0'; - num_token++; - /*LOGD("splitted msg : [%s], Index : %d", parse_str[num_token], num_token);*/ - } else { - LOGW("too long message : length %d [%s]", msg_length, recv_msg + prev_pos); + if (api == MUSE_RECORDER_API_GET_DEVICE_STATE) { + g_atomic_int_set(&cb_info->msg_recv_running, 0); + LOGD("get device state done. close client cb handler"); + } else { + switch (api) { + case MUSE_RECORDER_API_CREATE: + if (ret != RECORDER_ERROR_NONE) { + g_atomic_int_set(&cb_info->msg_recv_running, 0); + LOGE("create error 0x%x. closing..", ret); } - - prev_pos = str_pos + 1; - - if (num_token >= RECORDER_PARSED_STRING_NUM_MAX) { - LOGE("There's too many tokens. Remained msg length %d", ret - str_pos); - break; + break; + case MUSE_RECORDER_API_DESTROY: + if (ret == RECORDER_ERROR_NONE) { + g_atomic_int_set(&cb_info->msg_recv_running, 0); + LOGD("destroy done. closing.."); } + break; + default: + __recorder_get_api_operation(api, cb_info, msg); + break; } } - /*LOGD("num_token : %d", num_token);*/ + g_cond_signal(&cb_info->api_cond[api]); + g_mutex_unlock(&cb_info->api_mutex[api]); + } else if (api_class == MUSE_RECORDER_API_CLASS_THREAD_SUB || api == MUSE_RECORDER_CB_EVENT) { + __recorder_add_msg_to_queue(cb_info, api, event, event_class, msg); + } else { + LOGW("unknown recorder api %d and api_class %d", api, api_class); + } + + return; +} + - /* Re-construct to the useful single msg. */ - for (i = 0; i < num_token; i++) { - if (i >= RECORDER_PARSED_STRING_NUM_MAX) { - LOGE("invalid token index %d", i); +static void *_recorder_msg_handler_func(gpointer data) +{ + int api = 0; + int type = 0; + recorder_message_s *rec_msg = NULL; + recorder_idle_event_s *rec_idle_event = NULL; + recorder_msg_handler_info_s *handler_info = (recorder_msg_handler_info_s *)data; + recorder_cb_info_s *cb_info = NULL; + + if (!handler_info || !handler_info->cb_info) { + LOGE("NULL handler %p", handler_info); + return NULL; + } + + cb_info = (recorder_cb_info_s *)handler_info->cb_info; + type = handler_info->type; + + LOGD("t:%d start", type); + + g_mutex_lock(&handler_info->mutex); + + while (g_atomic_int_get(&handler_info->running)) { + if (g_queue_is_empty(handler_info->queue)) { + /*LOGD("signal wait...");*/ + g_cond_wait(&handler_info->cond, &handler_info->mutex); + /*LOGD("signal received");*/ + + if (g_atomic_int_get(&handler_info->running) == 0) { + LOGD("stop event thread"); break; } + } - api = -1; - api_class = -1; + rec_msg = (recorder_message_s *)g_queue_pop_head(handler_info->queue); + g_mutex_unlock(&handler_info->mutex); + if (rec_msg == NULL) { + LOGE("NULL message"); + g_mutex_lock(&handler_info->mutex); + continue; + } - if (!muse_recorder_msg_get(api, parse_str[i])) { - LOGE("failed to get recorder api"); - continue; - } + api = rec_msg->api; - if (api == MUSE_RECORDER_CB_EVENT) { - if (!muse_recorder_msg_get(event, parse_str[i]) || - !muse_recorder_msg_get(event_class, parse_str[i])) { - LOGE("failed to get event or event_class [%s]", parse_str[i]); - continue; - } + if (api < MUSE_RECORDER_API_MAX) { + int ret = 0; + + g_mutex_lock(&cb_info->api_mutex[api]); + + if (muse_recorder_msg_get(ret, rec_msg->recv_msg)) { + cb_info->api_ret[api] = ret; + cb_info->api_activating[api] = 1; + + /*LOGD("recorder api %d - return 0x%x", ret);*/ + + g_cond_signal(&cb_info->api_cond[api]); } else { - if (!muse_recorder_msg_get(api_class, parse_str[i])) { - LOGE("failed to get api_class [%s]", parse_str[i]); - continue; - } + LOGE("t:%d failed to get ret for api %d, msg %s", type, api, rec_msg->recv_msg); } - if (api_class == MUSE_RECORDER_API_CLASS_IMMEDIATE) { - if (api >= MUSE_RECORDER_API_MAX) { - LOGE("invalid api %d", api); - continue; + g_mutex_unlock(&cb_info->api_mutex[api]); + } else if (api == MUSE_RECORDER_CB_EVENT) { + switch (rec_msg->event_class) { + case MUSE_RECORDER_EVENT_CLASS_THREAD_SUB: + _recorder_client_user_callback(cb_info, rec_msg->recv_msg, rec_msg->event); + break; + case MUSE_RECORDER_EVENT_CLASS_THREAD_MAIN: + rec_idle_event = g_new0(recorder_idle_event_s, 1); + if (rec_idle_event == NULL) { + LOGE("event alloc failed"); + break; } - g_mutex_lock(&cb_info->api_mutex[api]); + rec_idle_event->event = rec_msg->event; + rec_idle_event->cb_info = cb_info; + g_mutex_init(&rec_idle_event->event_mutex); + strncpy(rec_idle_event->recv_msg, rec_msg->recv_msg, sizeof(rec_idle_event->recv_msg) - 1); - if (!muse_recorder_msg_get(ret, parse_str[i])) { - LOGE("failed to get recorder ret"); - g_mutex_unlock(&cb_info->api_mutex[api]); - continue; - } + /*LOGD("add recorder event[%d, %p] to IDLE", rec_msg->event, rec_idle_event);*/ - cb_info->api_ret[api] = ret; - cb_info->api_activating[api] = 1; + g_mutex_lock(&cb_info->idle_event_mutex); + cb_info->idle_event_list = g_list_append(cb_info->idle_event_list, (gpointer)rec_idle_event); + g_mutex_unlock(&cb_info->idle_event_mutex); - if (api == MUSE_RECORDER_API_GET_DEVICE_STATE) { - g_atomic_int_set(&cb_info->msg_recv_running, 0); - LOGD("get device state done. close client cb handler"); - } else { - switch (api) { - case MUSE_RECORDER_API_CREATE: - if (ret != RECORDER_ERROR_NONE) { - g_atomic_int_set(&cb_info->msg_recv_running, 0); - LOGE("create error 0x%x. closing..", ret); - } - break; - case MUSE_RECORDER_API_DESTROY: - if (ret == RECORDER_ERROR_NONE) { - g_atomic_int_set(&cb_info->msg_recv_running, 0); - LOGD("destroy done. closing.."); + g_idle_add_full(G_PRIORITY_DEFAULT, + (GSourceFunc)_recorder_idle_event_callback, + (gpointer)rec_idle_event, + NULL); + break; + default: + LOGE("unknown event class %d", rec_msg->event_class); + break; + } + } else { + LOGE("unknown api[%d] message", api); + } + + g_free(rec_msg); + rec_msg = NULL; + + g_mutex_lock(&handler_info->mutex); + } + + /* remove remained event */ + while (!g_queue_is_empty(handler_info->queue)) { + rec_msg = (recorder_message_s *)g_queue_pop_head(handler_info->queue); + if (rec_msg) { + LOGD("remove message %p", rec_msg); + free(rec_msg); + rec_msg = NULL; + } else { + LOGW("NULL message"); + } + } + + g_mutex_unlock(&handler_info->mutex); + + LOGD("return"); + + return NULL; +} + + +static void *_recorder_msg_recv_func(gpointer data) +{ + int recv_length = 0; + int single_length = 0; + int remained_length = 0; + char *recv_msg = NULL; + char *single_msg = NULL; + char *remained_msg = NULL; + int num_msg = 0; + int cur_pos = 0; + int prev_pos = 0; + recorder_cb_info_s *cb_info = (recorder_cb_info_s *)data; + + if (cb_info == NULL) { + LOGE("cb_info NULL"); + return NULL; + } + + LOGD("start"); + + single_msg = (char *)malloc(sizeof(char) * MUSE_RECORDER_MSG_MAX_LENGTH); + if (single_msg == NULL) { + LOGE("single_msg malloc failed"); + goto CB_HANDLER_EXIT; + } + + recv_msg = cb_info->recv_msg; + + while (g_atomic_int_get(&cb_info->msg_recv_running)) { + recv_length = muse_core_ipc_recv_msg(cb_info->fd, recv_msg); + if (recv_length <= 0) { + cb_info->is_server_connected = FALSE; + LOGE("receive msg failed - server disconnected"); + break; + } + + recv_msg[recv_length] = '\0'; + + cur_pos = 0; + prev_pos = 0; + num_msg = 0; + + /*LOGD("recv msg : %s, length : %d", recv_msg, recv_length);*/ + + /* Need to split the combined entering msgs */ + for (cur_pos = 0; cur_pos < recv_length; cur_pos++) { + if (recv_msg[cur_pos] == '}') { + single_length = cur_pos - prev_pos + 1; + + if (single_length < MUSE_RECORDER_MSG_MAX_LENGTH) { + /* check remained msg */ + if (remained_length > 0) { + if (remained_msg) { + strncpy(single_msg, remained_msg, remained_length); + strncpy(single_msg + remained_length, recv_msg + prev_pos, single_length); + single_msg[remained_length + single_length] = '\0'; + + free(remained_msg); + remained_msg = NULL; + } else { + strncpy(single_msg, recv_msg + prev_pos, single_length); + single_msg[single_length] = '\0'; + LOGE("lost msg [%s], skip...", single_msg); } - break; - default: - _recorder_get_api_operation(api, cb_info, parse_str[i]); - break; + + remained_length = 0; + } else { + strncpy(single_msg, recv_msg + prev_pos, single_length); + single_msg[single_length] = '\0'; + } + + if (single_msg[0] == '{') { + num_msg++; + /*LOGD("splitted msg : [%s], Index : %d", single_msg, num_msg);*/ + __recorder_process_msg(cb_info, single_msg); + } else { + LOGE("invalid msg [%s]", single_msg); } + } else { + LOGE("too long message [len %d] skip...", single_length); } - g_cond_signal(&cb_info->api_cond[api]); - g_mutex_unlock(&cb_info->api_mutex[api]); - } else if (api_class == MUSE_RECORDER_API_CLASS_THREAD_SUB || api == MUSE_RECORDER_CB_EVENT) { - __recorder_add_msg_to_queue(cb_info, api, event, event_class, parse_str[i]); + prev_pos = cur_pos + 1; + } + } + + /* check incompleted message */ + if (recv_msg[recv_length - 1] != '}') { + remained_length = recv_length - prev_pos; + + LOGW("incompleted message [len %d]", remained_length); + + remained_msg = (char *)malloc(remained_length + 1); + if (remained_msg) { + strncpy(remained_msg, recv_msg + prev_pos, remained_length); + remained_msg[remained_length] = '\0'; } else { - LOGW("unknown recorder api %d and api_class %d", api, api_class); + LOGE("failed to alloc for remained msg"); } + } else { + remained_length = 0; } } @@ -931,10 +959,11 @@ static void *_recorder_msg_recv_func(gpointer data) if (!cb_info->is_server_connected) { /* send error msg for server disconnection */ - error_msg = muse_core_msg_json_factory_new(MUSE_RECORDER_CB_EVENT, + char *error_msg = muse_core_msg_json_factory_new(MUSE_RECORDER_CB_EVENT, MUSE_TYPE_INT, "error", RECORDER_ERROR_SERVICE_DISCONNECTED, MUSE_TYPE_INT, "current_state", RECORDER_STATE_NONE, NULL); + if (!error_msg) { LOGE("error_msg failed"); goto CB_HANDLER_EXIT; @@ -955,16 +984,14 @@ static void *_recorder_msg_recv_func(gpointer data) } CB_HANDLER_EXIT: - if (parse_str) { - for (i = 0 ; i < RECORDER_PARSED_STRING_NUM_MAX ; i++) { - if (parse_str[i]) { - free(parse_str[i]); - parse_str[i] = NULL; - } - } + if (single_msg) { + free(single_msg); + single_msg = NULL; + } - free(parse_str); - parse_str = NULL; + if (remained_msg) { + free(remained_msg); + remained_msg = NULL; } return NULL;