#define MUSE_URI_MAX_LENGTH 4096
#define MUSE_MSG_MAX_LENGTH 4096
-typedef struct muse_module * muse_module_h;
+typedef struct muse_module *muse_module_h;
+typedef struct muse_client *muse_client_h;
typedef enum {
MUSE_MODULE_COMMAND_INITIALIZE = 0,
void muse_core_cmd_dispatch(muse_module_h module, muse_module_command_e cmd);
void muse_core_connection_close(int sock_fd);
int muse_core_client_new(void);
+muse_client_h muse_core_client_handle_new(void);
+int muse_core_client_handle_get_fd(muse_client_h muse_client);
int muse_core_client_new_data_ch(void);
int muse_core_client_get_msg_fd(muse_module_h module);
int muse_core_client_get_data_fd(muse_module_h module);
int muse_core_client_get_capi(muse_module_h module);
int muse_core_client_set_value(muse_module_h module, const char *value_name, int set_value);
int muse_core_client_get_value(muse_module_h module, const char *value_name, int *get_value);
+void muse_core_client_handle_free(muse_client_h muse_client);
void muse_core_worker_exit(muse_module_h module);
-unsigned muse_core_get_atomic_uint(void);
+unsigned int muse_core_get_atomic_uint(void);
#ifdef __cplusplus
}
typedef struct muse_core_ipc {
tbm_bufmgr bufmgr;
+ GHashTable *client_table;
+ gint *key;
void (*free)(void);
} muse_core_ipc_t;
gboolean muse_core_ipc_job_function(struct muse_core_workqueue_job * job);
int muse_core_ipc_send_msg(int sock_fd, const char *msg);
int muse_core_ipc_recv_msg(int sock_fd, char *msg);
+int muse_core_ipc_recv_msg_server(int sock_fd, char *msg);
+int muse_core_ipc_recv_msg_client(muse_client_h muse_client, char *msg);
void muse_core_ipc_set_timeout(int sock_fd, unsigned long timeout_sec);
gboolean muse_core_ipc_data_job_function(muse_core_workqueue_job_t * job);
int muse_core_ipc_push_data(int sock_fd, const char *data, int size, uint64_t data_id);
#endif
#include <sys/time.h>
+#include "muse_core.h"
#include "muse_core_msg_json.h"
-#define WRITE_DEFAULT_BLOCK_SIZE 4096
typedef struct muse_core_log {
int type;
char *buf;
size_t size;
- char cache[WRITE_DEFAULT_BLOCK_SIZE];
+ char cache[MUSE_MSG_MAX_LENGTH];
int log_fd;
int count;
void (*log)(char *);
gboolean is_create_api_called; /* If false, corresponding to the static function */
} muse_module_t;
+typedef struct muse_client {
+ int fd;
+ size_t cache_len;
+ char cache[MUSE_MSG_MAX_LENGTH * 2];
+ gboolean is_ever_broken;
+} muse_client_t;
+
typedef struct muse_core {
int fd;
int data_fd;
static int _muse_core_set_nonblocking(int fd, bool value);
static int _muse_core_check_server_is_running(void);
static muse_core_t *_muse_core_create_new_server_from_fd(int fd[], int type);
-static gboolean _muse_core_connection_handler(GIOChannel *source, GIOCondition condition, gpointer data);
static int _muse_core_free(muse_core_t *server);
+static int _muse_core_server_new(muse_core_channel_e channel);
+static gboolean _muse_core_connection_handler(GIOChannel *source, GIOCondition condition, gpointer data);
+static int _muse_core_client_new(muse_core_channel_e channel);
static int _muse_core_set_nonblocking(int fd, bool value)
{
return retval;
}
-int _muse_core_server_new(muse_core_channel_e channel)
+static int _muse_core_server_new(muse_core_channel_e channel)
{
int fd;
struct sockaddr_un addr_un;
if (channel == MUSE_CHANNEL_MSG) {
if ((module = malloc(sizeof(muse_module_t))) == NULL) {
- LOGE("failed to allocated memory for client stat");
+ LOGE("failed to allocated memory for muse_module_t");
goto out;
}
char err_msg[MAX_ERROR_MSG_LEN] = {'\0',};
LOGD("Enter");
- if (channel >= MUSE_CHANNEL_MAX)
- return -1;
+ g_return_val_if_fail(channel < MUSE_CHANNEL_MAX, -1);
/*Create socket*/
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
return sockfd;
}
+static muse_client_h _muse_core_client_handle_new(muse_core_channel_e channel)
+{
+ muse_client_h muse_client;
+
+ g_return_val_if_fail(channel < MUSE_CHANNEL_MAX, NULL);
+
+ muse_client = malloc(sizeof(muse_client_t));
+ g_return_val_if_fail(muse_client, NULL);
+
+ memset(muse_client, 0, sizeof(muse_client_t));
+ muse_client->fd = _muse_core_client_new(channel);
+
+ return muse_client;
+}
+
gpointer muse_core_main_loop(gpointer data)
{
#if 0
g_module_symbol(module->ch[MUSE_CHANNEL_MSG].dll_handle, CMD_DISPATCHER, (gpointer *)&cmd_dispatcher);
- if (cmd_dispatcher && cmd_dispatcher[cmd]) {
- LOGD("cmd_dispatcher: %p", cmd_dispatcher);
+ if (cmd_dispatcher && cmd_dispatcher[cmd])
cmd_dispatcher[cmd](module);
- }
}
int muse_core_client_new(void)
return _muse_core_client_new(MUSE_CHANNEL_MSG);
}
+muse_client_h muse_core_client_handle_new(void)
+{
+ return _muse_core_client_handle_new(MUSE_CHANNEL_MSG);
+}
+
+int muse_core_client_handle_get_fd(muse_client_h muse_client)
+{
+ g_return_val_if_fail(muse_client, MM_ERROR_INVALID_ARGUMENT);
+
+ return muse_client->fd;
+}
+
int muse_core_client_new_data_ch(void)
{
return _muse_core_client_new(MUSE_CHANNEL_DATA);
}
}
+void muse_core_client_handle_free(muse_client_h muse_client)
+{
+ g_return_if_fail(muse_client);
+
+ muse_core_connection_close(muse_client->fd);
+ MUSE_FREE(muse_client);
+}
+
void muse_core_worker_exit(muse_module_h module)
{
LOGD("Enter");
g_thread_exit(NULL);
}
-unsigned muse_core_get_atomic_uint(void)
+unsigned int muse_core_get_atomic_uint(void)
{
static guint atom = 0;
#include "muse_core_msg_json.h"
#include "muse_core_module.h"
+#define END_DELIM '}'
+#define RECV_ERR -1
+
typedef struct muse_recv_data_head {
unsigned int marker;
uint64_t id;
/* Dynamic allocated data area */
} muse_recv_data_t;
-static muse_core_ipc_t *g_muse_core_ipc;
+static muse_core_ipc_t *g_muse_core_ipc = NULL;
static void _muse_core_ipc_client_cleanup(muse_module_h module);
static gpointer _muse_core_ipc_dispatch_worker(gpointer data);
static gpointer _muse_core_ipc_data_worker(gpointer data);
static muse_recv_data_t *_muse_core_ipc_new_qdata(char **recvBuff, int recvSize, int *allocSize);
+static bool _muse_core_ipc_msg_complete_confirm(muse_client_h client, char *msg, int msg_len);
static bool _muse_core_ipc_init_bufmgr(void);
static void _muse_core_ipc_deinit_bufmgr(void);
+static void _muse_core_ipc_client_free(gpointer key, gpointer value, gpointer user_data);
static void _muse_core_ipc_free(void);
static void _muse_core_ipc_init_instance(void (*free)(void));
g_return_if_fail(module != NULL);
muse_core_log_get_instance()->flush_msg();
+ g_hash_table_foreach(g_muse_core_ipc->client_table, (GHFunc)_muse_core_ipc_client_free, NULL);
+
g_queue_free(module->ch[MUSE_CHANNEL_DATA].queue);
module->ch[MUSE_CHANNEL_DATA].queue = NULL;
g_cond_broadcast(&module->ch[MUSE_CHANNEL_DATA].cond);
_muse_core_ipc_client_cleanup(module);
} else {
parse_len = len;
- LOGD("Message In");
cmd = 0;
api_module = 0;
module->msg_offset = 0;
g_mutex_init(&module->ch[MUSE_CHANNEL_DATA].mutex);
}
}
- LOGD("[default] module's dll_handle: %p", module->ch[MUSE_CHANNEL_MSG].dll_handle);
muse_core_module_get_instance()->dispatch(cmd, module);
if (module->is_create_api_called == false)
_muse_core_ipc_client_cleanup(module);
intptr_t module_addr = 0;
if (muse_core_msg_json_deserialize(MUSE_MODULE_ADDR, recvBuff, NULL, &module_addr, NULL, MUSE_TYPE_POINTER)) {
module = (muse_module_h) module_addr;
- if (module)
+ if (module) {
module->ch[MUSE_CHANNEL_DATA].p_gthread = g_thread_self();
+ g_return_val_if_fail(module->ch[MUSE_CHANNEL_DATA].p_gthread != NULL, NULL);
+ }
}
MUSE_FREE(recvBuff);
recvBuff = NULL;
return qData;
}
+static bool _muse_core_ipc_msg_complete_confirm(muse_client_h client, char *msg, int msg_len)
+{
+ char *ptr = NULL;
+ size_t ptr_len = 0;
+
+ g_return_val_if_fail(client != NULL, TRUE);
+ g_return_val_if_fail(msg != NULL, TRUE);
+
+ if (msg_len == MUSE_MSG_MAX_LENGTH || client->is_ever_broken == TRUE) {
+ ptr = strrchr(msg, END_DELIM);
+ g_return_val_if_fail(ptr != NULL, TRUE);
+ ptr_len = strlen(ptr) - 1;
+
+ if (ptr_len > 0) {
+ client->is_ever_broken = TRUE;
+ int idx = ptr - msg;
+ memcpy(client->cache, ptr + 1, ptr_len);
+ client->cache_len = ptr_len;
+ msg[idx + 1] = '\0';
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
static bool _muse_core_ipc_init_bufmgr(void)
{
LOGD("Enter");
LOGD("Leave");
}
+static void _muse_core_ipc_client_new(int sock_fd, muse_client_h client)
+{
+ g_return_if_fail(g_muse_core_ipc != NULL);
+ g_return_if_fail(g_muse_core_ipc->client_table != NULL);
+ g_return_if_fail(g_muse_core_ipc->key != NULL);
+
+ *(g_muse_core_ipc->key) = sock_fd;
+
+ g_hash_table_insert(g_muse_core_ipc->client_table, g_muse_core_ipc->key, (gpointer)client);
+}
+
+static void _muse_core_ipc_client_free(gpointer key, gpointer value, gpointer user_data)
+{
+ g_hash_table_remove(g_muse_core_ipc->client_table, key);
+}
+
static void _muse_core_ipc_free(void)
{
LOGD("Enter");
g_return_if_fail(g_muse_core_ipc != NULL);
+ g_hash_table_destroy(g_muse_core_ipc->client_table);
+ MUSE_FREE(g_muse_core_ipc->key);
MUSE_FREE(g_muse_core_ipc);
LOGD("Leave");
g_muse_core_ipc = calloc(1, sizeof(*g_muse_core_ipc));
g_return_if_fail(g_muse_core_ipc != NULL);
+ g_muse_core_ipc->client_table = g_hash_table_new(g_int_hash, g_int_equal);
+ g_return_if_fail(g_muse_core_ipc->client_table != NULL);
+
g_return_if_fail(_muse_core_ipc_init_bufmgr() == TRUE);
+ g_muse_core_ipc->key = g_new(gint, 1);
+ g_return_if_fail(g_muse_core_ipc->key != NULL);
g_muse_core_ipc->free = free;
}
{
LOGD("Enter");
muse_module_h module = NULL;
+ muse_client_h client = NULL;
g_return_val_if_fail(job != NULL, FALSE);
LOGD("[%p] client's fd : %d", module, module->ch[MUSE_CHANNEL_MSG].fd);
+ client = calloc(1, sizeof(muse_client_t));
+ g_return_val_if_fail(client != NULL, FALSE);
+
+ _muse_core_ipc_client_new(module->ch[MUSE_CHANNEL_MSG].fd, client);
+
module->ch[MUSE_CHANNEL_MSG].p_gthread = g_thread_new(NULL, _muse_core_ipc_dispatch_worker, (gpointer)module);
g_return_val_if_fail(module->ch[MUSE_CHANNEL_MSG].p_gthread != NULL, FALSE);
if ((ret = send(sock_fd, msg, strlen(msg), 0)) < 0) {
strerror_r(errno, err_msg, MAX_ERROR_MSG_LEN);
LOGE("fail to send msg (%s)", err_msg);
- } else {
- LOGD("[strlen: %d] %s", ret, msg);
}
return ret;
{
int ret = MM_ERROR_NONE;
char err_msg[MAX_ERROR_MSG_LEN] = {'\0',};
- g_return_val_if_fail(msg != NULL, MM_ERROR_INVALID_ARGUMENT);
+
+ g_return_val_if_fail(msg != NULL, RECV_ERR);
if ((ret = recv(sock_fd, msg, MUSE_MSG_MAX_LENGTH, 0)) < 0) {
strerror_r(errno, err_msg, MAX_ERROR_MSG_LEN);
LOGE("fail to receive msg (%s)", err_msg);
} else if (ret > 0) {
msg[ret] = '\0';
- LOGD("[strlen: %d] %s", ret, msg);
+ }
+
+ return ret;
+}
+
+int muse_core_ipc_recv_msg_server(int sock_fd, char *msg)
+{
+ int ret = MM_ERROR_NONE;
+ int recv_len = 0;
+ char err_msg[MAX_ERROR_MSG_LEN] = {'\0',};
+
+ g_return_val_if_fail(msg != NULL, RECV_ERR);
+
+ *(g_muse_core_ipc->key) = sock_fd;
+ muse_client_h client = g_hash_table_lookup(g_muse_core_ipc->client_table, g_muse_core_ipc->key);
+
+ g_return_val_if_fail(client != NULL, RECV_ERR);
+
+ if (client->cache_len > 0)
+ memcpy(msg, client->cache, client->cache_len);
+
+ recv_len = MUSE_MSG_MAX_LENGTH - client->cache_len;
+
+ if ((ret = recv(sock_fd, msg + client->cache_len, recv_len, 0)) < 0) {
+ strerror_r(errno, err_msg, MAX_ERROR_MSG_LEN);
+ LOGE("fail to receive msg (%s)", err_msg);
+ } else if (ret > 0) {
+ if (client->cache_len > 0) {
+ ret += client->cache_len;
+ client->cache_len = 0;
+ }
+ msg[ret] = '\0';
+ if (_muse_core_ipc_msg_complete_confirm(client, msg, ret) == FALSE)
+ LOGW("%s", client->cache);
+ }
+
+ return ret;
+}
+
+int muse_core_ipc_recv_msg_client(muse_client_h client, char *msg)
+{
+ int ret = MM_ERROR_NONE;
+ int recv_len = 0;
+ char err_msg[MAX_ERROR_MSG_LEN] = {'\0',};
+
+ g_return_val_if_fail(client != NULL, RECV_ERR);
+ g_return_val_if_fail(msg != NULL, RECV_ERR);
+
+ if (client->cache_len > 0)
+ memcpy(msg, client->cache, client->cache_len);
+
+ recv_len = MUSE_MSG_MAX_LENGTH - client->cache_len;
+
+ if ((ret = recv(client->fd, msg + client->cache_len, recv_len, 0)) < 0) {
+ strerror_r(errno, err_msg, MAX_ERROR_MSG_LEN);
+ LOGE("fail to receive msg (%s)", err_msg);
+ } else if (ret > 0) {
+ if (client->cache_len > 0) {
+ ret += client->cache_len;
+ client->cache_len = 0;
+ }
+ msg[ret] = '\0';
+ if (_muse_core_ipc_msg_complete_confirm(client, msg, ret) == FALSE)
+ LOGW("%s", client->cache);
}
return ret;
#define U32BITS 0xffffffff
#define MAX_FILE_NUM 3
#define MAX_SIZE 33554432
+#define WRITE_FAIL -1
static muse_core_log_t *g_muse_core_log = NULL;
if (g_muse_core_log) {
static char client_buf[256];
snprintf(client_buf, sizeof(client_buf), "[client name] %s", muse_core_config_get_instance()->get_host(muse_core_module_get_instance()->api_module));
- if (write(g_muse_core_log->log_fd, client_buf, strlen(client_buf)) != (int)strlen(client_buf))
+ if (write(g_muse_core_log->log_fd, client_buf, strlen(client_buf)) == WRITE_FAIL)
LOGE("There was an error writing client name to logfile");
- else if (write(g_muse_core_log->log_fd, "\n", 1) != 1)
+ else if (write(g_muse_core_log->log_fd, "\n", 1) != WRITE_FAIL)
LOGE("write %s", client_buf);
snprintf(client_buf, sizeof(client_buf), "[client pid] %lu", (unsigned long) getpid());
- if (write(g_muse_core_log->log_fd, client_buf, strlen(client_buf)) != (int)strlen(client_buf))
+ if (write(g_muse_core_log->log_fd, client_buf, strlen(client_buf)) == WRITE_FAIL)
LOGE("There was an error writing client pid to logfile");
- else if (write(g_muse_core_log->log_fd, "\n", 1) != 1)
+ else if (write(g_muse_core_log->log_fd, "\n", 1) == WRITE_FAIL)
LOGE("write %s", client_buf);
snprintf(client_buf, sizeof(client_buf), "[client's latest called api] %s", _muse_core_log_get_msg());
- if (write(g_muse_core_log->log_fd, client_buf, strlen(client_buf)) != (int)strlen(client_buf))
+ if (write(g_muse_core_log->log_fd, client_buf, strlen(client_buf)) == WRITE_FAIL)
LOGE("There was an error writing client's latest called api to logfile");
- else if (write(g_muse_core_log->log_fd, "\n", 1) != 1)
+ else if (write(g_muse_core_log->log_fd, "\n", 1) == WRITE_FAIL)
LOGE("write %s", client_buf);
}
g_return_if_fail(g_muse_core_log != NULL);
g_muse_core_log->buf = NULL;
g_muse_core_log->size = 0;
- memset(g_muse_core_log->cache, 0, WRITE_DEFAULT_BLOCK_SIZE);
+ memset(g_muse_core_log->cache, 0, MUSE_MSG_MAX_LENGTH);
g_muse_core_log->log = log;
g_muse_core_log->fatal = fatal;
g_muse_core_log->count = 0;
return;
}
- if (strlen(g_muse_core_log->cache) + strlen(msg) < WRITE_DEFAULT_BLOCK_SIZE) {
+ if (strlen(g_muse_core_log->cache) + strlen(msg) < MUSE_MSG_MAX_LENGTH) {
_muse_core_log_write_buffer(msg, strlen(msg));
} else {
- if (write(g_muse_core_log->log_fd, g_muse_core_log->cache, strlen(g_muse_core_log->cache)) == (int)strlen(g_muse_core_log->cache)) {
- memset(g_muse_core_log->cache, 0, WRITE_DEFAULT_BLOCK_SIZE);
+ if (write(g_muse_core_log->log_fd, g_muse_core_log->cache, strlen(g_muse_core_log->cache)) != WRITE_FAIL) {
+ memset(g_muse_core_log->cache, 0, MUSE_MSG_MAX_LENGTH);
_muse_core_log_write_buffer(msg, strlen(msg));
- } else {
- LOGE("There was an error writing to logfile");
}
}
}
g_return_if_fail(module->ch[MUSE_CHANNEL_MSG].dll_handle != NULL);
- LOGD("cmd: %d\t module's dll_handle: %p", cmd, module->ch[MUSE_CHANNEL_MSG].dll_handle);
g_module_symbol(module->ch[MUSE_CHANNEL_MSG].dll_handle, DISPATCHER, (gpointer *)&dispatcher);
if (dispatcher && dispatcher[cmd]) {
- LOGD("dispatcher: %p", dispatcher);
dispatcher[cmd](module);
} else {
LOGE("error - dispatcher");
key_len = strlen(find_key);
json_object_object_foreach(jobj, key, val) {
- if (strlen(key) == key_len && !memcmp(key, find_key, key_len)) {
- LOGD("key %s: value %s", key, json_object_get_string(val));
+ if (strlen(key) == key_len && !memcmp(key, find_key, key_len))
return val;
- }
- }
-
- return NULL;
-}
-
-static json_object *_muse_core_msg_json_find_key(const char *find_key, json_object *jso)
-{
- size_t key_len = 0;
-
- g_return_val_if_fail(jso != NULL, NULL);
-
- g_return_val_if_fail(find_key != NULL, NULL);
-
- key_len = strlen(find_key);
-
- json_object_object_foreach(jso, key, val) {
- if (strlen(key) == key_len && !memcmp(key, find_key, key_len)) {
- LOGD("[%s] : %s", key, json_object_to_json_string(val));
- return val;
- }
}
return NULL;
while ((type = va_arg(ap, int)) != 0) {
name = va_arg(ap, char *);
- LOGD("[type:#%d] key: %s ", type, name);
switch (type) {
case MUSE_TYPE_INT:
json_object_object_add(jobj, name, json_object_new_int(va_arg(ap, int32_t)));
sndMsg = g_strdup(jsonMsg);
muse_core_log_get_instance()->set_msg(sndMsg);
- LOGD("json msg : %s", sndMsg);
-
json_object_put(jobj);
return sndMsg;
case json_type_int:
if (m_type == MUSE_TYPE_ANY || m_type == MUSE_TYPE_INT) {
*(int32_t *)data = json_object_get_int(val);
- LOGD("json_type_int (%s) value: %d", key, *(int32_t *)data);
} else if (m_type == MUSE_TYPE_INT64) {
*(int64_t *)data = json_object_get_int64(val);
- LOGD("json_type_int (%s) value: %" G_GINT64_FORMAT "", key, *(int64_t *)data);
} else if (m_type == MUSE_TYPE_POINTER) {
if (sizeof(intptr_t) == 8)
*(intptr_t *)data = json_object_get_int64(val);
else
*(intptr_t *)data = json_object_get_int(val);
- LOGD("json_type_int (%s) value: %p", key, *(intptr_t *)data);
} else if (m_type == MUSE_TYPE_DOUBLE) {
*(double *)data = json_object_get_double(val);
- LOGD("json_type_double (%s) value: %.20lf", key, *(double *)data);
}
break;
case json_type_object:
- LOGD("json_type_object (%s) value: %d", key, json_object_get_object(val));
break;
case json_type_string:
strncpy((char *)data, json_object_get_string(val), strlen(json_object_get_string(val)));
- LOGD("json_type_string (%s) value: %s", key, (char *)data);
break;
case json_type_array:
LOGD("json_type_array (%s)", key);
g_return_val_if_fail(jobj != NULL, FALSE);
g_return_val_if_fail(data != NULL, FALSE);
- val = _muse_core_msg_json_find_key(key, (json_object *)jobj);
+ val = _muse_core_msg_json_find_obj((json_object *)jobj, key);
if (!val) {
LOGE("\"%s\" key is not founded", key);
json_object_put(jobj);
umask(0);
result = chdir("/");
- LOGD("result = %d sid: %5d pgid: %5d pid: %5d ppid: %5d", result, (int)getsid(0), (int)getpgid(0), (int)getpid(), (int)getppid());
+ LOGD("result = %d sid: %d pgid: %d pid: %d ppid: %d", result, (int)getsid(0), (int)getpgid(0), (int)getpid(), (int)getppid());
return muse_core_run();
}