--- /dev/null
+YoungHun Kim <yh8004.kim@samsung.com>\r
+Hee Chul Jeon <heechul.jeon@samsung.com>\r
+JongHyuk Choi <jhchoi.choi@samsung.com>\r
--- /dev/null
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "mused")
+
+PROJECT(${fw_name})
+
+SET(SRCS
+ src/mmsvc_core.c
+ src/mmsvc_core_config.c
+ src/mmsvc_core_ipc.c
+ src/mmsvc_core_log.c
+ src/mmsvc_core_module.c
+ src/mmsvc_core_msg_json.c
+ src/mmsvc_core_tool.c
+ src/mmsvc_core_workqueue.c
+ )
+SET(SRC-SERVER
+ src/mmsvc_core_server.c
+ )
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(BINDIR "${PREFIX}/bin")
+SET(INC_DIR include)
+INCLUDE_DIRECTORIES(${INC_DIR})
+
+SET(dependents "dlog json-c glib-2.0 mm-common gmodule-2.0 iniparser")
+SET(pc_dependents "dlog mm-common")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_name} REQUIRED ${dependents})
+FOREACH(flag ${${fw_name}_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "-I./include ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -std=gnu99")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+IF("${ARCH}" STREQUAL "arm")
+ ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib")
+
+aux_source_directory(src SOURCES)
+#ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
+ADD_LIBRARY(${fw_name} SHARED ${SRCS})
+
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${fw_name}
+ PROPERTIES
+ VERSION ${FULLVER}
+ SOVERSION ${MAJORVER}
+ CLEAN_DIRECT_OUTPUT 1
+)
+
+ADD_EXECUTABLE(mused-server ${SRC-SERVER})
+TARGET_LINK_LIBRARIES(mused-server ${pkgs_LDFLAGS} ${fw_name} ${CMAKE_DL_LIBS})
+INSTALL(TARGETS mused-server DESTINATION ${BINDIR})
+
+INSTALL(TARGETS ${fw_name} DESTINATION lib)
+INSTALL(
+ DIRECTORY ${INC_DIR}/ DESTINATION include/media
+ FILES_MATCHING
+ PATTERN "*_private.h" EXCLUDE
+ PATTERN "${INC_DIR}/*.h"
+ )
+
+SET(PC_NAME ${fw_name})
+SET(PC_REQUIRED ${pc_dependents})
+SET(PC_LDFLAGS -l${fw_name})
+SET(PC_CFLAGS -I\${includedir}/media)
+
+CONFIGURE_FILE(
+ ${fw_name}.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+ ${CMAKE_CURRENT_SOURCE_DIR}/config/${fw_name}.conf
+ @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/config/${fw_name}.conf DESTINATION /usr/share/${fw_name})
+
+IF(UNIX)
+
+ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
+ADD_CUSTOM_COMMAND(
+ DEPENDS clean
+ COMMENT "distribution clean"
+ COMMAND find
+ ARGS .
+ -not -name config.cmake -and \(
+ -name tester.c -or
+ -name Testing -or
+ -name CMakeFiles -or
+ -name cmake.depends -or
+ -name cmake.check_depends -or
+ -name CMakeCache.txt -or
+ -name cmake.check_cache -or
+ -name *.cmake -or
+ -name Makefile -or
+ -name core -or
+ -name core.* -or
+ -name gmon.out -or
+ -name install_manifest.txt -or
+ -name *.pc -or
+ -name *~ \)
+ | grep -v TC | xargs rm -rf
+ TARGET distclean
+ VERBATIM
+)
+
+ENDIF(UNIX)
+
--- /dev/null
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+ Apache License\r
+ Version 2.0, January 2004\r
+ http://www.apache.org/licenses/\r
+\r
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+ 1. Definitions.\r
+\r
+ "License" shall mean the terms and conditions for use, reproduction,\r
+ and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+ "Licensor" shall mean the copyright owner or entity authorized by\r
+ the copyright owner that is granting the License.\r
+\r
+ "Legal Entity" shall mean the union of the acting entity and all\r
+ other entities that control, are controlled by, or are under common\r
+ control with that entity. For the purposes of this definition,\r
+ "control" means (i) the power, direct or indirect, to cause the\r
+ direction or management of such entity, whether by contract or\r
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+ outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+ "You" (or "Your") shall mean an individual or Legal Entity\r
+ exercising permissions granted by this License.\r
+\r
+ "Source" form shall mean the preferred form for making modifications,\r
+ including but not limited to software source code, documentation\r
+ source, and configuration files.\r
+\r
+ "Object" form shall mean any form resulting from mechanical\r
+ transformation or translation of a Source form, including but\r
+ not limited to compiled object code, generated documentation,\r
+ and conversions to other media types.\r
+\r
+ "Work" shall mean the work of authorship, whether in Source or\r
+ Object form, made available under the License, as indicated by a\r
+ copyright notice that is included in or attached to the work\r
+ (an example is provided in the Appendix below).\r
+\r
+ "Derivative Works" shall mean any work, whether in Source or Object\r
+ form, that is based on (or derived from) the Work and for which the\r
+ editorial revisions, annotations, elaborations, or other modifications\r
+ represent, as a whole, an original work of authorship. For the purposes\r
+ of this License, Derivative Works shall not include works that remain\r
+ separable from, or merely link (or bind by name) to the interfaces of,\r
+ the Work and Derivative Works thereof.\r
+\r
+ "Contribution" shall mean any work of authorship, including\r
+ the original version of the Work and any modifications or additions\r
+ to that Work or Derivative Works thereof, that is intentionally\r
+ submitted to Licensor for inclusion in the Work by the copyright owner\r
+ or by an individual or Legal Entity authorized to submit on behalf of\r
+ the copyright owner. For the purposes of this definition, "submitted"\r
+ means any form of electronic, verbal, or written communication sent\r
+ to the Licensor or its representatives, including but not limited to\r
+ communication on electronic mailing lists, source code control systems,\r
+ and issue tracking systems that are managed by, or on behalf of, the\r
+ Licensor for the purpose of discussing and improving the Work, but\r
+ excluding communication that is conspicuously marked or otherwise\r
+ designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+ "Contributor" shall mean Licensor and any individual or Legal Entity\r
+ on behalf of whom a Contribution has been received by Licensor and\r
+ subsequently incorporated within the Work.\r
+\r
+ 2. Grant of Copyright License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ copyright license to reproduce, prepare Derivative Works of,\r
+ publicly display, publicly perform, sublicense, and distribute the\r
+ Work and such Derivative Works in Source or Object form.\r
+\r
+ 3. Grant of Patent License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ (except as stated in this section) patent license to make, have made,\r
+ use, offer to sell, sell, import, and otherwise transfer the Work,\r
+ where such license applies only to those patent claims licensable\r
+ by such Contributor that are necessarily infringed by their\r
+ Contribution(s) alone or by combination of their Contribution(s)\r
+ with the Work to which such Contribution(s) was submitted. If You\r
+ institute patent litigation against any entity (including a\r
+ cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+ or a Contribution incorporated within the Work constitutes direct\r
+ or contributory patent infringement, then any patent licenses\r
+ granted to You under this License for that Work shall terminate\r
+ as of the date such litigation is filed.\r
+\r
+ 4. Redistribution. You may reproduce and distribute copies of the\r
+ Work or Derivative Works thereof in any medium, with or without\r
+ modifications, and in Source or Object form, provided that You\r
+ meet the following conditions:\r
+\r
+ (a) You must give any other recipients of the Work or\r
+ Derivative Works a copy of this License; and\r
+\r
+ (b) You must cause any modified files to carry prominent notices\r
+ stating that You changed the files; and\r
+\r
+ (c) You must retain, in the Source form of any Derivative Works\r
+ that You distribute, all copyright, patent, trademark, and\r
+ attribution notices from the Source form of the Work,\r
+ excluding those notices that do not pertain to any part of\r
+ the Derivative Works; and\r
+\r
+ (d) If the Work includes a "NOTICE" text file as part of its\r
+ distribution, then any Derivative Works that You distribute must\r
+ include a readable copy of the attribution notices contained\r
+ within such NOTICE file, excluding those notices that do not\r
+ pertain to any part of the Derivative Works, in at least one\r
+ of the following places: within a NOTICE text file distributed\r
+ as part of the Derivative Works; within the Source form or\r
+ documentation, if provided along with the Derivative Works; or,\r
+ within a display generated by the Derivative Works, if and\r
+ wherever such third-party notices normally appear. The contents\r
+ of the NOTICE file are for informational purposes only and\r
+ do not modify the License. You may add Your own attribution\r
+ notices within Derivative Works that You distribute, alongside\r
+ or as an addendum to the NOTICE text from the Work, provided\r
+ that such additional attribution notices cannot be construed\r
+ as modifying the License.\r
+\r
+ You may add Your own copyright statement to Your modifications and\r
+ may provide additional or different license terms and conditions\r
+ for use, reproduction, or distribution of Your modifications, or\r
+ for any such Derivative Works as a whole, provided Your use,\r
+ reproduction, and distribution of the Work otherwise complies with\r
+ the conditions stated in this License.\r
+\r
+ 5. Submission of Contributions. Unless You explicitly state otherwise,\r
+ any Contribution intentionally submitted for inclusion in the Work\r
+ by You to the Licensor shall be under the terms and conditions of\r
+ this License, without any additional terms or conditions.\r
+ Notwithstanding the above, nothing herein shall supersede or modify\r
+ the terms of any separate license agreement you may have executed\r
+ with Licensor regarding such Contributions.\r
+\r
+ 6. Trademarks. This License does not grant permission to use the trade\r
+ names, trademarks, service marks, or product names of the Licensor,\r
+ except as required for reasonable and customary use in describing the\r
+ origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+ 7. Disclaimer of Warranty. Unless required by applicable law or\r
+ agreed to in writing, Licensor provides the Work (and each\r
+ Contributor provides its Contributions) on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ implied, including, without limitation, any warranties or conditions\r
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+ PARTICULAR PURPOSE. You are solely responsible for determining the\r
+ appropriateness of using or redistributing the Work and assume any\r
+ risks associated with Your exercise of permissions under this License.\r
+\r
+ 8. Limitation of Liability. In no event and under no legal theory,\r
+ whether in tort (including negligence), contract, or otherwise,\r
+ unless required by applicable law (such as deliberate and grossly\r
+ negligent acts) or agreed to in writing, shall any Contributor be\r
+ liable to You for damages, including any direct, indirect, special,\r
+ incidental, or consequential damages of any character arising as a\r
+ result of this License or out of the use or inability to use the\r
+ Work (including but not limited to damages for loss of goodwill,\r
+ work stoppage, computer failure or malfunction, or any and all\r
+ other commercial damages or losses), even if such Contributor\r
+ has been advised of the possibility of such damages.\r
+\r
+ 9. Accepting Warranty or Additional Liability. While redistributing\r
+ the Work or Derivative Works thereof, You may choose to offer,\r
+ and charge a fee for, acceptance of support, warranty, indemnity,\r
+ or other liability obligations and/or rights consistent with this\r
+ License. However, in accepting such obligations, You may act only\r
+ on Your own behalf and on Your sole responsibility, not on behalf\r
+ of any other Contributor, and only if You agree to indemnify,\r
+ defend, and hold each Contributor harmless for any liability\r
+ incurred by, or claims asserted against, such Contributor by reason\r
+ of your accepting any such warranty or additional liability.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ APPENDIX: How to apply the Apache License to your work.\r
+\r
+ To apply the Apache License to your work, attach the following\r
+ boilerplate notice, with the fields enclosed by brackets "[]"\r
+ replaced with your own identifying information. (Don't include\r
+ the brackets!) The text should be enclosed in the appropriate\r
+ comment syntax for the file format. We also recommend that a\r
+ file or class name and description of purpose be included on the\r
+ same "printed page" as the copyright notice for easier\r
+ identification within third-party archives.\r
+\r
+ Copyright [yyyy] [name of copyright owner]\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+\r
+\r
--- /dev/null
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
--- /dev/null
+[mused]
+; The 'hosts' parameter defines the modules,
+; which the user would like to connect to the museD.
+hosts=player, camera, recorder
+logfile=/var/log/mused.log
+
+[player]
+; The 'player' parameter represents the mused-player.
+; This module recovers the "capi-media-player".
+path=/usr/lib/libmused-player.so
+
+[camera]
+; The 'camera' parameter represents the mused-camera.
+; This module recovers the "capi-media-camera".
+path=/usr/lib/libmused-camera.so
+
+[recorder]
+; The 'recorder' parameter represents the mused-recorder.
+; This module recovers the "capi-media-recorder".
+; This one should be paired with the 'camera' module.
+path=/usr/lib/libmused-recorder.so
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MMSVC_CORE_H__
+#define __MMSVC_CORE_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#define MM_URI_MAX_LENGTH 100
+#define MM_MSG_MAX_LENGTH 1024*1024
+
+typedef struct __Client * Client;
+
+int mmsvc_core_run();
+void mmsvc_core_connection_close(int sock_fd);
+int mmsvc_core_client_new(void);
+int mmsvc_core_client_new_data_ch(void);
+int mmsvc_core_client_get_msg_fd(Client client);
+int mmsvc_core_client_get_data_fd(Client client);
+void mmsvc_core_client_set_cust_data(Client client, void *data);
+void *mmsvc_core_client_get_cust_data(Client client);
+char *mmsvc_core_client_get_msg(Client client);
+int mmsvc_core_client_get_capi(Client client);
+void mmsvc_core_worker_exit(Client client);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__MMSVC_CORE_H__*/
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MMSVC_CORE_CONFIG_H__
+#define __MMSVC_CORE_CONFIG_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#include <iniparser.h>
+
+#define CONFFILE "/usr/share/mused/mused.conf"
+#define HOST_MAX_COUNT 1024
+#define MUSEDHOST "mused:hosts"
+#define MUSEDLOG "mused:logfile"
+#define COLON ":"
+#define COMMA ","
+#define PATH "path"
+
+typedef struct host_info
+{
+ char *path;
+} host_info_t;
+
+typedef struct config
+{
+ char *hosts;
+ int type;
+ char *logfile;
+ host_info_t *host_infos[HOST_MAX_COUNT];
+ dictionary *mmsvc_dict;
+ void (*free)(void);
+ char* (*get_path)(int);
+} config_t;
+
+/*mmsvc_core_config_init must be called before mmsvc_core_config_get_instance*/
+config_t *mmsvc_core_config_get_instance(void);
+void mmsvc_core_config_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MMSVC_CORE_CONFIG_H__ */
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MMSVC_CORE_INTERNAL_H__
+#define __MMSVC_CORE_INTERNAL_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <limits.h>
+#include <errno.h>
+#include <err.h>
+#include <glib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <gmodule.h>
+#include <stdbool.h>
+#include <dlog.h>
+#include <syslog.h>
+#include <execinfo.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/un.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#undef LOG_TAG
+#define LOG_TAG "TIZEN_N_MUSED"
+#define MUSED_DIR "/var/run/mused"
+#define LOGFILE "/tmp/mmsvc_core_log"
+#define LOCKFILE "/tmp/.mmsvc-core.lock"
+#define SOCKFILE0 "/tmp/mmsvc_core_socket"
+#define SOCKFILE1 "/tmp/mmsvc_core_data_socket"
+
+#define TIMEOUT 0x01
+/** Wait for a socket or FD to become readable */
+#define READ 0x02
+/** Wait for a socket or FD to become writeable */
+#define WRITE 0x04
+/** Wait for a POSIX signal to be raised*/
+#define SIGNAL 0x08
+#define PERSIST 0x10
+/** Select edge-triggered behavior, if supported by the backend. */
+#define EDGETRIGGERED 0x20
+
+#define DISPATCHER "dispatcher"
+#define MMSVC_FREE(src) { if(src) {g_free(src); src = NULL;} }
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__MMSVC_CORE_INTERNAL_H__*/
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __MMSVC_CORE_IPC_H__
+#define __MMSVC_CORE_IPC_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#include "mmsvc_core.h"
+#include "mmsvc_core_workqueue.h"
+
+#define MUSED_DATA_HEAD 0xda1a6ead
+
+typedef enum {
+ API_CREATE,
+ API_DESTROY,
+ API_MAX
+} api_type_e;
+
+gboolean mmsvc_core_ipc_job_function(struct mmsvc_core_workqueue_job * job);
+int mmsvc_core_ipc_send_msg(int sock_fd, const char *msg);
+int mmsvc_core_ipc_recv_msg(int sock_fd, char *msg);
+
+gboolean mmsvc_core_ipc_data_job_function(mmsvc_core_workqueue_job_t * job);
+int mmsvc_core_ipc_push_data(int sock_fd, const char *data, int size, int data_id);
+char *mmsvc_core_ipc_get_data(Client client);
+void mmsvc_core_ipc_delete_data(char *data);
+
+/**
+ * @brief Create and send address of server side client infomation structure.
+ * @remarks Does NOT guarantee thread safe.
+ * @param[in] client The server side client infomation.
+ * @param[in] fd socket fd
+ */
+#define mmsvc_core_send_client_addr(client, fd) \
+ do{ \
+ char *__sndMsg__; \
+ int __len__; \
+ __sndMsg__ = mmsvc_core_msg_json_factory_new(0, #client, client, \
+ 0); \
+ __len__ = mmsvc_core_ipc_send_msg(fd, __sndMsg__); \
+ mmsvc_core_msg_json_factory_free(__sndMsg__); \
+ if (__len__ <= 0) { \
+ LOGE("sending message failed"); \
+ return PLAYER_ERROR_INVALID_OPERATION; \
+ } \
+ }while(0)
+
+
+#ifdef _cplusplus
+}
+#endif
+
+#endif /*__MMSVC_CORE_IPC_H__*/
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __MMSVC_CORE_LOG_H__
+#define __MMSVC_CORE_LOG_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include <gmodule.h>
+#include "mmsvc_core_msg_json.h"
+
+typedef struct mmsvc_core_log {
+ int type;
+ unsigned refs;
+ char *buf;
+ size_t len;
+ int log_fd;
+ int count;
+ GTimer *timer;
+ void (*log)(char *);
+ void (*fatal)(char *);
+ void (*set_module_value) (int, GModule *, gboolean);
+ gboolean (*get_module_opened) (int);
+ GModule* (*get_module_value) (int);
+ gboolean module_opened[MMSVC_CLIENT_MAX];
+ GModule *module[MMSVC_CLIENT_MAX];
+} mmsvc_core_log_t;
+
+/*mmsvc_core_log_init must be called before mmsvc_core_log_get_instance*/
+mmsvc_core_log_t *mmsvc_core_log_get_instance(void);
+void mmsvc_core_log_init(void);
+
+#ifdef _cplusplus
+}
+#endif
+
+#endif /*__MMSVC_CORE_LOG_H__*/
\ No newline at end of file
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __MMSVC_CORE_MODULE_H__
+#define __MMSVC_CORE_MODULE_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#include "mmsvc_core.h"
+#include "mmsvc_core_internal.h"
+
+typedef gboolean (*MMSVC_MODULE_DispatchFunc) (Client client);
+
+GModule * mmsvc_core_module_load(int api_client);
+void mmsvc_core_module_dll_symbol(int cmd, Client client);
+gboolean mmsvc_core_module_close(Client client);
+
+#ifdef _cplusplus
+}
+#endif
+
+#endif /*__MMSVC_CORE_MODULE_H__*/
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MMSVC_CORE_MSG_JSON_H__
+#define __MMSVC_CORE_MSG_JSON_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#include <glib.h>
+
+typedef enum {
+ MMSVC_PLAYER,
+ MMSVC_CAMERA,
+ MMSVC_RECORDER,
+ MMSVC_CLIENT_MAX
+} mmsvc_api_client_e;
+
+enum {
+ MUSED_TYPE_INT = 1,
+ MUSED_TYPE_DOUBLE,
+ MUSED_TYPE_STRING,
+ MUSED_TYPE_ARRAY,
+ MUSED_TYPE_MAX
+};
+
+typedef enum {
+ MUSED_MSG_PARSE_ERROR_NONE,
+ MUSED_MSG_PARSE_ERROR_CONTINUE,
+ MUSED_MSG_PARSE_ERROR_OTHER,
+ MUSED_MSG_PARSE_ERROR_MAX
+} mused_msg_parse_err_e;
+
+char * mmsvc_core_msg_json_factory_new(int api, const char *arg_name, int arg, ...);
+void mmsvc_core_msg_json_factory_free(char * msg);
+gboolean mmsvc_core_msg_json_deserialize(char *key, char* buf, void *data, mused_msg_parse_err_e *err);
+gboolean mmsvc_core_msg_json_deserialize_len(char *key, char* buf, int *parse_len, void *data, mused_msg_parse_err_e *err);
+
+#ifdef _cplusplus
+}
+#endif
+
+#endif /*__MMSVC_CORE_MSG_JSON_H__*/
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __MMSVC_CORE_PRIVATE_H__
+#define __MMSVC_CORE_PRIVATE_H__
+
+#include <glib.h>
+#include <gmodule.h>
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+typedef gboolean(*MMSVC_CORE_ClientCallback) (GIOChannel * source, GIOCondition condition, gpointer data);
+
+typedef enum {
+ MUSED_CHANNEL_MSG,
+ MUSED_CHANNEL_DATA,
+ MUSED_CHANNEL_MAX
+} mused_channel_e;
+
+typedef struct {
+ GThread * p_gthread;
+ int fd;
+ union {
+ GModule *module;
+ struct {
+ GQueue *queue;
+ GMutex mutex;
+ GCond cond;
+ };
+ };
+} channel_info;
+
+typedef struct __Client{
+ channel_info ch[MUSED_CHANNEL_MAX];
+ char recvMsg[MM_MSG_MAX_LENGTH];
+ int msg_offset;
+ int api_client;
+ gpointer cust_data;
+} _Client;
+
+typedef struct {
+ int fd;
+ int data_fd;
+ int type;
+ int stop;
+ int retval;
+ gint running;
+} MMServer;
+
+gpointer mmsvc_core_main_loop(gpointer data);
+MMServer *mmsvc_core_new();
+gboolean mmsvc_core_connection_handler(GIOChannel * source, GIOCondition condition, gpointer data);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__MMSVC_CORE_PRIVATE_H__*/
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __MMSVC_CORE_TOOL_H__
+#define __MMSVC_CORE_TOOL_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+void mmsvc_core_tool_parse_params(int argc, char **argv);
+void mmsvc_core_tool_recursive_rmdir(const char *path);
+
+#ifdef _cplusplus
+}
+#endif
+
+#endif /*__MMSVC_CORE_TOOL_H__*/
--- /dev/null
+/**
+* Multithreaded work queue.
+* Copyright (c) 2012 Ronald Bennett Cemer
+* This software is licensed under the BSD license.
+* See the accompanying LICENSE.txt for details.
+*/
+
+#ifndef __MMSVC_CORE_WORKQUEUE_H__
+#define __MMSVC_CORE_WORKQUEUE_H__
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#include "mmsvc_core_internal.h"
+#include "mmsvc_core_log.h"
+
+typedef struct mmsvc_core_workqueue_job {
+ gboolean(*job_function) (struct mmsvc_core_workqueue_job * job);
+ void *user_data;
+ struct mmsvc_core_workqueue_job *prev;
+ struct mmsvc_core_workqueue_job *next;
+} mmsvc_core_workqueue_job_t;
+
+typedef struct mmsvc_core_workqueue_workqueue {
+ struct mmsvc_core_workqueue_worker *workers;
+ struct mmsvc_core_workqueue_job *waiting_jobs;
+ pthread_mutex_t jobs_mutex;
+ pthread_cond_t jobs_cond;
+ void (*shutdown)(void);
+ void (*add_job)(mmsvc_core_workqueue_job_t *);
+} mmsvc_core_workqueue_workqueue_t;
+
+typedef struct mmsvc_core_workqueue_worker {
+ pthread_t thread;
+ int terminate;
+ struct mmsvc_core_workqueue_workqueue *workqueue;
+ struct mmsvc_core_workqueue_worker *prev;
+ struct mmsvc_core_workqueue_worker *next;
+} mmsvc_core_workqueue_worker_t;
+
+mmsvc_core_workqueue_workqueue_t *mmsvc_core_workqueue_get_instance(void);
+int mmsvc_core_workqueue_init(int numWorkers);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MMSVC_CORE_WORKQUEUE_H__ */
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+ <assign>
+ <filesystem path="/usr/bin/mused-server" label="_" exec_label="none" />
+
+ </assign>
+</manifest>
--- /dev/null
+
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib
+includedir=/usr/include/media
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@ mm-common iniparser
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
+
--- /dev/null
+[Unit]
+Description=Mused server
+After=vconf-setup.service
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/mused-server
+Restart=always
+RestartSec=0
+MemoryLimit=100M
+User=system
+Group=system
+SmackProcessLabel=mused-server
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+[Socket]
+SocketUser=system
+SocketGroup=system
+ListenStream=/tmp/.mmsvc_core_socket
+SmackLabelIPIn=mused-server
+SmackLabelIPOut=mused-server
+Service=mused.service
+
+[Install]
+WantedBy=sockets.target
--- /dev/null
+Name: mused
+Summary: A Media Daemon library in Tizen Native API
+Version: 0.1.1
+Release: 0
+Group: TO_BE/FILLED_IN
+License: TO BE FILLED IN
+Source0: %{name}-%{version}.tar.gz
+Source1: mused.service
+Source2: mused.socket
+BuildRequires: cmake
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(mm-common)
+BuildRequires: pkgconfig(iniparser)
+BuildRequires: pkgconfig(json-c)
+#BuildRequires: pkgconfig(mm-session)
+#BuildRequires: pkgconfig(mm-sound)
+#BuildRequires: pkgconfig(mm-player)
+#BuildRequires: pkgconfig(mm-ta)
+#BuildRequires: pkgconfig(capi-base-common)
+#BuildRequires: pkgconfig(capi-media-sound-manager)
+#BuildRequires: pkgconfig(gstreamer-0.10)
+#BuildRequires: pkgconfig(gstreamer-plugins-base-0.10)
+#BuildRequires: pkgconfig(gstreamer-interfaces-0.10)
+#BuildRequires: pkgconfig(gstreamer-app-0.10)
+#BuildRequires: pkgconfig(appcore-efl)
+#BuildRequires: pkgconfig(elementary)
+#BuildRequires: pkgconfig(ecore)
+#BuildRequires: pkgconfig(evas)
+#BuildRequires: pkgconfig(ecore-x)
+#BuildRequires: pkgconfig(capi-media-tool)
+#BuildRequires: pkgconfig(libtbm)
+#BuildRequires: pkgconfig(mmutil-imgp)
+#BuildRequires: pkgconfig(audio-session-mgr)
+#BuildRequires: pkgconfig(vconf)
+#BuildRequires: pkgconfig(icu-i18n)
+#BuildRequires: pkgconfig(utilX)
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description
+
+
+%package devel
+Summary: A Media Daemon library in Tizen (Development)
+Group: TO_BE/FILLED_IN
+Requires: %{name} = %{version}-%{release}
+Requires: pkgconfig(mm-common)
+Requires: pkgconfig(iniparser)
+%description devel
+
+%prep
+%setup -q
+
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE -D_GNU_SOURCE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE -D_GNU_SOURCE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE -D_GNU_SOURCE"
+%endif
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+#mkdir -p %{buildroot}/opt/usr/devel
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+mkdir -p %{buildroot}/usr/bin
+cp mused-server %{buildroot}/usr/bin
+
+%make_install
+
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+install -m 0644 %SOURCE1 %{buildroot}%{_libdir}/systemd/system/mused.service
+ln -s ../mused.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/mused.service
+
+mkdir -p %{buildroot}%{_libdir}/systemd/system/sockets.target.wants
+install -m 0644 %SOURCE2 %{buildroot}%{_libdir}/systemd/system/mused.socket
+ln -s ../mused.socket %{buildroot}%{_libdir}/systemd/system/sockets.target.wants/mused.socket
+
+%post
+/sbin/ldconfig
+chown 200:200 %{_libdir}/systemd/system/mused.socket
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%manifest mused.manifest
+%defattr(-,system,system,-)
+%{_libdir}/libmused.so.*
+%{_datadir}/license/%{name}
+%{_libdir}/systemd/system/mused.service
+%{_libdir}/systemd/system/multi-user.target.wants/mused.service
+%{_libdir}/systemd/system/sockets.target.wants/mused.socket
+%{_libdir}/systemd/system/mused.socket
+%{_datadir}/mused/mused.conf
+/usr/bin/*
+
+
+%files devel
+%defattr(-,system,system,-)
+%{_includedir}/media/*.h
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/libmused.so
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mmsvc_core.h"
+#include "mmsvc_core_private.h"
+#include "mmsvc_core_config.h"
+#include "mmsvc_core_internal.h"
+#include "mmsvc_core_ipc.h"
+#include "mmsvc_core_log.h"
+#include "mmsvc_core_workqueue.h"
+
+#define FILENAMELEN 32
+#define WORK_THREAD_NUM 8
+#define LOG_SLEEP_TIMER 10
+
+static MMServer *server;
+static GMainLoop *g_loop;
+static GThread *g_thread;
+static char *UDS_files[MUSED_CHANNEL_MAX] = {SOCKFILE0, SOCKFILE1};
+
+static gboolean (*job_functions[MUSED_CHANNEL_MAX])
+ (mmsvc_core_workqueue_job_t *job) = {
+ mmsvc_core_ipc_job_function,
+ mmsvc_core_ipc_data_job_function
+ };
+
+static int _mmsvc_core_set_nonblocking(int fd);
+static int _mmsvc_core_check_server_is_running(void);
+static MMServer *_mmsvc_core_create_new_server_from_fd(int fd[], int type);
+static gboolean _mmsvc_core_connection_handler(GIOChannel *source,
+ GIOCondition condition, gpointer data);
+static int _mmsvc_core_free(MMServer *server);
+
+static int _mmsvc_core_set_nonblocking(int fd)
+{
+ int flags = fcntl(fd, F_GETFL, NULL);
+
+ if (flags >= 0) {
+ LOGD("fcntl nonblocking");
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+ LOGE("fcntl(%d, F_SETFL)", fd);
+ return -1;
+ } else {
+ LOGD("fcntl(%d, F_SETFL)");
+ }
+ }
+
+ return 0;
+}
+
+static int _mmsvc_core_check_server_is_running(void)
+{
+ int fd, already_running;
+ int ret = -1;
+
+ LOGD("Enter");
+
+ /* First, check whether the existing file is locked. */
+ fd = open(LOCKFILE, O_RDONLY);
+ if (fd == -1 && errno != ENOENT) {
+ /* Cannot open file, but it's not because the file doesn't exist. */
+ char msg[1024];
+ snprintf(msg, sizeof(msg), "datserver: Cannot open lock file %s", LOCKFILE);
+ LOGE("open failed: %s ", msg);
+ return ret;
+ } else if (fd != -1) {
+ already_running = flock(fd, LOCK_EX | LOCK_NB) == -1;
+ close(fd);
+ if (already_running) {
+ LOGE("File already locked. There's already a server running");
+ return 0;
+ }
+ }
+
+ /* Lock file does not exist, or is not locked. Create a new lockfile and lock it. */
+ fd = open(LOCKFILE, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd == -1) {
+ LOGE("dataserver: Cannot create lock file");
+ return ret;
+ }
+
+ if (flock(fd, LOCK_EX | LOCK_NB) != 0) {
+ LOGE("Can't lock the lock file \"%s\". " "Is another instance running?", LOCKFILE);
+ return ret;
+ }
+
+ /* Close out the standard file descriptors */
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+
+ LOGD("Leave");
+ return 1;
+}
+
+static bool _mmsvc_core_attach_server(int fd, MMSVC_CORE_ClientCallback callback, gpointer param)
+{
+ GIOChannel *channel;
+ GSource *src = NULL;
+
+ LOGD("Enter");
+
+ channel = g_io_channel_unix_new(fd);
+ if (!channel) {
+ return false;
+ }
+
+ src = g_io_create_watch(channel, G_IO_IN);
+ if (!src) {
+ return false;
+ }
+
+ g_source_set_callback(src, (GSourceFunc) callback, param, NULL);
+
+ g_source_attach(src, g_main_loop_get_context(g_loop));
+ g_source_unref(src);
+
+ return true;
+}
+
+static MMServer *_mmsvc_core_create_new_server_from_fd(int fd[], int type)
+{
+ MMServer *server;
+ int i;
+
+ LOGD("Enter");
+ server = malloc(sizeof(MMServer));
+ g_return_val_if_fail(server != NULL, NULL);
+
+ server->fd = fd[MUSED_CHANNEL_MSG];
+ server->data_fd = fd[MUSED_CHANNEL_DATA];
+ server->type = type;
+ server->stop = 0;
+ server->retval = 0;
+
+ /*initiate server */
+ g_atomic_int_set(&server->running, 1);
+
+ for (i = 0; i < MUSED_CHANNEL_MAX; i++) {
+ if (!_mmsvc_core_attach_server(fd[i],
+ _mmsvc_core_connection_handler, (gpointer) i)) {
+ LOGD("Fail to attach server fd %d", fd[i]);
+ MMSVC_FREE(server);
+ return NULL;
+ }
+ }
+
+ LOGD("Leave");
+ return server;
+}
+
+static int _mmsvc_core_free(MMServer *server)
+{
+ int retval = -1;
+ int i;
+ LOGD("Enter");
+
+ g_return_val_if_fail(server != NULL, retval);
+
+ retval = server->retval;
+ close(server->fd);
+ for (i = 0; i < MUSED_CHANNEL_MAX; i++)
+ remove(UDS_files[i]);
+ remove(LOCKFILE);
+ MMSVC_FREE(server);
+ mmsvc_core_workqueue_get_instance()->shutdown();
+ LOGD("Leave");
+ return retval;
+}
+
+gpointer mmsvc_core_main_loop(gpointer data)
+{
+ while (1) {
+ sleep(LOG_SLEEP_TIMER);
+ LOGD("polling %d\n", g_main_loop_is_running(g_loop));
+ }
+
+ return NULL;
+}
+
+int _mmsvc_core_server_new(mused_channel_e channel)
+{
+ int fd;
+ struct sockaddr *address;
+ struct sockaddr_un addr_un;
+ socklen_t address_len;
+
+ if (channel >= MUSED_CHANNEL_MAX)
+ return -1;
+
+ unlink(UDS_files[channel]);
+ LOGD("Enter");
+
+ /* Create Socket */
+ fd = socket(AF_UNIX, SOCK_STREAM, 0); /* Unix Domain Socket */
+ if (fd < 0) {
+ LOGE("socket failed sock: %s", strerror(errno));
+ return -1;
+ } else {
+ LOGD("fd: %d", fd);
+ }
+
+ memset(&addr_un, 0, sizeof(addr_un));
+ addr_un.sun_family = AF_UNIX;
+ strncpy(addr_un.sun_path, UDS_files[channel], sizeof(addr_un.sun_path));
+ address_len = sizeof(addr_un);
+ address = (struct sockaddr *)(&addr_un);
+
+ /* Bind to filename */
+ if (bind(fd, address, address_len) < 0) {
+ if (errno == EADDRINUSE) {
+ LOGE("%d is address in using so remove the file of %s", fd, addr_un.sun_path);
+ unlink(addr_un.sun_path);
+ }
+
+ if (bind(fd, (struct sockaddr *)&addr_un, sizeof(addr_un)) != 0)
+ LOGE("bind failed sock: %s", strerror(errno));
+ else
+ LOGE("bind failed sock: %s", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ /* Setup listen queue */
+ if (listen(fd, 5) == -1) {
+ LOGE("listen failed");
+ close(fd);
+ return -1;
+ }
+
+ if (_mmsvc_core_set_nonblocking(fd) < 0)
+ LOGE("failed to set server socket to non-blocking");
+
+ LOGD("Leave");
+
+ return fd;
+}
+
+
+MMServer *mmsvc_core_new()
+{
+ int fd[MUSED_CHANNEL_MAX];
+ int i;
+ LOGD("Enter");
+
+ for (i = 0; i < MUSED_CHANNEL_MAX; i++) {
+ fd[i] = _mmsvc_core_server_new(i);
+ if (fd[i] < 0) {
+ LOGE("Failed to create socket server %d", i);
+ return NULL;
+ }
+ }
+
+ /* Initialize work queue */
+ if (mmsvc_core_workqueue_init(WORK_THREAD_NUM)) {
+ LOGE("mmsvc_core_new : Failed to initialize the workqueue");
+ for (i = 0; i < MUSED_CHANNEL_MAX; i++)
+ close(fd[i]);
+ mmsvc_core_workqueue_get_instance()->shutdown();
+ return NULL;
+ }
+
+ LOGD("Leave");
+
+ return _mmsvc_core_create_new_server_from_fd(fd, READ|PERSIST);
+}
+
+static gboolean _mmsvc_core_connection_handler(GIOChannel *source,
+ GIOCondition condition, gpointer data)
+{
+ int client_sockfd, server_sockfd;
+ socklen_t client_len;
+ struct sockaddr_un client_address;
+ mused_channel_e channel = (mused_channel_e)data;
+
+ LOGD("Enter");
+
+ Client client = NULL;
+ mmsvc_core_workqueue_job_t *job = NULL;
+
+ server_sockfd = g_io_channel_unix_get_fd(source);
+
+ client_len = sizeof(client_address);
+ client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);
+ LOGD("server: %d client: %d", server_sockfd, client_sockfd);
+
+ if (client_sockfd < 0) {
+ LOGE("failed to accept");
+ goto out;
+ }
+
+ if (channel == MUSED_CHANNEL_MSG) {
+ if ((client = malloc(sizeof(_Client))) == NULL) {
+ LOGE("failed to allocated memory for client stat");
+ goto out;
+ }
+
+ memset(client, 0, sizeof(_Client));
+ client->ch[channel].fd = client_sockfd;
+ }
+
+ if ((job = malloc(sizeof(mmsvc_core_workqueue_job_t))) == NULL) {
+ LOGE("failed to allocate memory for job state");
+ goto out;
+ }
+
+ job->job_function = job_functions[channel];
+ if (channel == MUSED_CHANNEL_MSG)
+ job->user_data = client;
+ else
+ job->user_data = (void *)client_sockfd;
+
+ mmsvc_core_workqueue_get_instance()->add_job(job);
+
+ LOGD("Leave");
+ return TRUE;
+out:
+ if (client_sockfd)
+ close(client_sockfd);
+
+ MMSVC_FREE(client);
+ MMSVC_FREE(job);
+
+ LOGE("FALSE");
+ return FALSE;
+}
+
+int mmsvc_core_run()
+{
+ int ret = -1;
+
+ LOGD("Enter");
+
+ ret = _mmsvc_core_check_server_is_running();
+ if (ret == -1) {
+ return -1;
+ } else if (ret == 0) {
+ LOGE("Server is already running");
+ return 2;
+ }
+
+ /* Sigaction */
+ g_loop = g_main_loop_new(NULL, FALSE);
+
+ g_thread = g_thread_new("mmsvc_thread", mmsvc_core_main_loop, g_loop);
+
+ server = mmsvc_core_new();
+ if (!server) {
+ g_main_loop_unref(g_loop);
+ return 1;
+ }
+
+ LOGD("g_main_loop_run");
+ g_main_loop_run(g_loop);
+
+ LOGD("Leave");
+ return _mmsvc_core_free(server);
+}
+
+static int _mmsvc_core_client_new(mused_channel_e channel)
+{
+ struct sockaddr_un address;
+ int len, ret = -1;
+ int sockfd;
+
+ if (channel >= MUSED_CHANNEL_MAX)
+ return -1;
+
+ LOGD("Enter");
+
+ /*Create socket*/
+ if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ LOGE("[socket failure] sock: %s", strerror(errno));
+ return ret;
+ } else {
+ LOGD("sockfd: %d", sockfd);
+ if (fcntl(sockfd, F_SETFD, FD_CLOEXEC) < 0) {
+ LOGE("unable to set on ctrls socket fd %d: %s", sockfd, strerror(errno));
+ (void) close(sockfd);
+ return -1;
+ }
+ LOGD("fcntl");
+ }
+
+ memset(&address, 0, sizeof(address));
+ address.sun_family = AF_UNIX;
+ strncpy(address.sun_path, UDS_files[channel], sizeof(address.sun_path));
+ len = sizeof(address);
+
+ if ((ret = connect(sockfd, (struct sockaddr *)&address, len)) < 0) {
+ LOGE("connect failure");
+ if (sockfd)
+ (void) close(sockfd);
+ return ret;
+ }
+
+ LOGD("Leave");
+ return sockfd;
+}
+
+int mmsvc_core_client_new(void)
+{
+ return _mmsvc_core_client_new(MUSED_CHANNEL_MSG);
+}
+
+int mmsvc_core_client_new_data_ch(void)
+{
+ return _mmsvc_core_client_new(MUSED_CHANNEL_DATA);
+}
+
+int mmsvc_core_client_get_msg_fd(Client client)
+{
+ g_return_val_if_fail(client, -1);
+
+ return client->ch[MUSED_CHANNEL_MSG].fd;
+}
+
+int mmsvc_core_client_get_data_fd(Client client)
+{
+ g_return_val_if_fail(client, -1);
+
+ return client->ch[MUSED_CHANNEL_DATA].fd;
+}
+void mmsvc_core_client_set_cust_data(Client client, void *data)
+{
+ g_return_if_fail(client);
+ client->cust_data = data;
+}
+
+void *mmsvc_core_client_get_cust_data(Client client)
+{
+ g_return_val_if_fail(client, NULL);
+ return client->cust_data;
+}
+
+char *mmsvc_core_client_get_msg(Client client)
+{
+ g_return_val_if_fail(client, NULL);
+ return (client->recvMsg + client->msg_offset);
+}
+
+int mmsvc_core_client_get_capi(Client client)
+{
+ g_return_val_if_fail(client, -1);
+ return client->api_client;
+}
+
+void mmsvc_core_connection_close(int sock_fd)
+{
+ LOGD("Enter");
+ if (sock_fd > 0) {
+ shutdown(sock_fd, SHUT_RDWR);
+ close(sock_fd);
+ }
+
+ LOGD("Leave");
+}
+
+void mmsvc_core_worker_exit(Client client)
+{
+ LOGD("Enter");
+ if (!client) {
+ LOGE("Error - null client");
+ return;
+ }
+
+ mmsvc_core_connection_close(client->ch[MUSED_CHANNEL_MSG].fd);
+ mmsvc_core_connection_close(client->ch[MUSED_CHANNEL_DATA].fd);
+ if (!client->ch[MUSED_CHANNEL_MSG].p_gthread) {
+ LOGE("Error - null p_gthread");
+ return;
+ }
+ LOGD("%p thread exit\n", client->ch[MUSED_CHANNEL_MSG].p_gthread);
+ g_thread_unref(client->ch[MUSED_CHANNEL_MSG].p_gthread);
+
+ if (client->ch[MUSED_CHANNEL_DATA].p_gthread)
+ g_thread_unref(client->ch[MUSED_CHANNEL_DATA].p_gthread);
+ MMSVC_FREE(client);
+
+ mmsvc_core_config_get_instance()->free();
+
+ LOGD("Leave");
+ g_thread_exit(NULL);
+}
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mmsvc_core_config.h"
+#include "mmsvc_core_internal.h"
+
+static config_t *g_conf = NULL;
+
+static int _mmsvc_core_config_parser(void);
+static void _mmsvc_core_config_free(void);
+static void _mmsvc_core_config_init_instance(void (*free)(void), char* (*get_path)(int));
+static char *_mmsvc_core_config_get_path(int api_client);
+
+static int _mmsvc_core_config_parser(void)
+{
+ char *host;
+ char *str;
+ int ret = -1;
+
+ g_return_val_if_fail(g_conf != NULL, ret);
+
+ g_conf->mmsvc_dict = iniparser_load(CONFFILE);
+ g_return_val_if_fail(g_conf->mmsvc_dict != NULL, ret);
+
+ str = iniparser_getstring(g_conf->mmsvc_dict, MUSEDHOST, NULL);
+ g_return_val_if_fail(str != NULL, ret);
+
+ g_conf->hosts = (char *) malloc(1 + strlen(str));
+ if (!g_conf->hosts) {
+ LOGE("Error - hosts allocation");
+ iniparser_freedict(g_conf->mmsvc_dict);
+ MMSVC_FREE(g_conf);
+ }
+ strcpy(g_conf->hosts, str);
+
+ str = iniparser_getstring(g_conf->mmsvc_dict, MUSEDLOG, NULL);
+ g_return_val_if_fail(str != NULL, ret);
+
+ g_conf->logfile = (char *) malloc(1 + strlen(str));
+ if (!g_conf->logfile) {
+ LOGE("Error - hosts allocation");
+ iniparser_freedict(g_conf->mmsvc_dict);
+ MMSVC_FREE(g_conf->hosts);
+ MMSVC_FREE(g_conf);
+ }
+ strcpy(g_conf->logfile, str);
+
+ g_conf->type = 0;
+ host = strtok(g_conf->hosts, COMMA);
+
+ while (host != NULL) {
+ char *host_name = (char *) malloc(HOST_MAX_COUNT);
+ if (!host_name) {
+ LOGE("Error - null host_name");
+ iniparser_freedict(g_conf->mmsvc_dict);
+ MMSVC_FREE(g_conf->hosts);
+ MMSVC_FREE(g_conf);
+ return ret;
+ }
+
+ LOGD("host: %s", host);
+ /* path */
+ strcpy(host_name, host);
+ strcat(host_name, COLON);
+ strcat(host_name, PATH);
+ g_strstrip(host_name); /*Removes leading and trailing whitespace from a string*/
+
+ g_conf->host_infos[g_conf->type] = (host_info_t *) malloc(sizeof(host_info_t));
+ if (!g_conf->host_infos[g_conf->type]) {
+ LOGE("Error - null type");
+ iniparser_freedict(g_conf->mmsvc_dict);
+ MMSVC_FREE(g_conf->hosts);
+ MMSVC_FREE(host_name);
+ MMSVC_FREE(g_conf->host_infos[g_conf->type]);
+ MMSVC_FREE(g_conf);
+ return ret;
+ }
+
+ g_conf->host_infos[g_conf->type]->path = (char *) malloc(1 + strlen(iniparser_getstring(g_conf->mmsvc_dict, host_name, NULL)));
+ if(!g_conf->host_infos[g_conf->type]->path) {
+ LOGE("Error - null path");
+ iniparser_freedict(g_conf->mmsvc_dict);
+ MMSVC_FREE(g_conf->hosts);
+ MMSVC_FREE(host_name);
+ MMSVC_FREE(g_conf->host_infos[g_conf->type]);
+ MMSVC_FREE(g_conf);
+ return ret;
+ }
+
+ strcpy(g_conf->host_infos[g_conf->type]->path, iniparser_getstring(g_conf->mmsvc_dict, host_name, NULL));
+ LOGD("[%d] %s", g_conf->type, g_conf->host_infos[g_conf->type]->path);
+
+ host = strtok(NULL, COMMA);
+ g_conf->type++;
+ MMSVC_FREE(host_name);
+ }
+
+ iniparser_freedict(g_conf->mmsvc_dict);
+ return 0;
+}
+
+static void _mmsvc_core_config_free(void)
+{
+ char *host;
+
+ g_return_if_fail(g_conf != NULL);
+
+ host = strtok(g_conf->hosts, COMMA);
+ g_conf->type = 0;
+
+ while (host != NULL) {
+ LOGD("host: %s", host);
+ MMSVC_FREE(g_conf->host_infos[g_conf->type]->path);
+ MMSVC_FREE(g_conf->host_infos[g_conf->type]);
+ host = strtok(NULL, COMMA);
+ g_conf->type++;
+ }
+ MMSVC_FREE(g_conf->hosts);
+ MMSVC_FREE(g_conf);
+}
+
+static void _mmsvc_core_config_init_instance(void (*free)(void), char* (*get_path)(int))
+{
+ g_return_if_fail(free != NULL);
+ g_return_if_fail(get_path != NULL);
+ g_return_if_fail(g_conf == NULL);
+
+ g_conf = calloc(1, sizeof(*g_conf));
+ g_conf->hosts = NULL;
+ g_conf->type = 0;
+ g_conf->logfile = NULL;
+ g_conf->mmsvc_dict = NULL;
+ g_conf->free = free;
+ g_conf->get_path = get_path;
+ LOGD("conf: %0x2x", g_conf);
+
+ if (_mmsvc_core_config_parser() != 0)
+ LOGE("parser() error");
+}
+
+static char *_mmsvc_core_config_get_path(int api_client)
+{
+ g_return_val_if_fail(g_conf->host_infos[api_client]->path != NULL, NULL);
+
+ LOGD("%s", g_conf->host_infos[api_client]->path);
+ return g_conf->host_infos[api_client]->path;
+}
+
+config_t *mmsvc_core_config_get_instance(void)
+{
+ if (g_conf == NULL)
+ _mmsvc_core_config_init_instance(_mmsvc_core_config_free, _mmsvc_core_config_get_path);
+
+ return g_conf;
+}
+
+void mmsvc_core_config_init(void)
+{
+ LOGD("Enter");
+ if (g_conf == NULL)
+ _mmsvc_core_config_init_instance(_mmsvc_core_config_free, _mmsvc_core_config_get_path);
+ LOGD("Leave");
+}
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mmsvc_core.h"
+#include "mmsvc_core_private.h"
+#include "mmsvc_core_config.h"
+#include "mmsvc_core_internal.h"
+#include "mmsvc_core_log.h"
+#include "mmsvc_core_ipc.h"
+#include "mmsvc_core_msg_json.h"
+#include "mmsvc_core_module.h"
+
+typedef struct {
+ int marker;
+ int id;
+ int size;
+} RecvDataHead_t;
+
+typedef struct {
+ RecvDataHead_t header;
+ /* Dynamic allocated data area */
+} RecvData_t;
+
+static gpointer _mmsvc_core_ipc_dispatch_worker(gpointer data);
+static gpointer _mmsvc_core_ipc_data_worker(gpointer data);
+static RecvData_t *_mmsvc_core_ipc_new_qdata(char **recvBuff, int recvSize, int *allocSize);
+
+static gpointer _mmsvc_core_ipc_dispatch_worker(gpointer data)
+{
+ int len, parse_len, cmd, api_client;
+ Client client = NULL;
+ int handle = 0;
+ mused_msg_parse_err_e err = MUSED_MSG_PARSE_ERROR_NONE;
+ g_return_val_if_fail(data != NULL, NULL);
+
+ client = (Client)data;
+ g_return_val_if_fail(client != NULL, NULL);
+
+ while (1) {
+ memset(client->recvMsg, 0x00, sizeof(client->recvMsg));
+ len = mmsvc_core_ipc_recv_msg(client->ch[MUSED_CHANNEL_MSG].fd, client->recvMsg);
+ if (len <= 0) {
+ LOGE("recv : %s (%d)", strerror(errno), errno);
+
+ LOGD("close module");
+ mmsvc_core_module_close(client);
+
+ LOGD("worker exit");
+ mmsvc_core_worker_exit(client);
+ break;
+ } else {
+ parse_len = len;
+ LOGD("Message In");
+ cmd = 0;
+ api_client = 0;
+ client->msg_offset = 0;
+
+ mmsvc_core_log_get_instance()->log(client->recvMsg);
+
+ while (client->msg_offset < len) {
+ if (mmsvc_core_msg_json_deserialize_len("api", client->recvMsg + client->msg_offset, &parse_len, &cmd, &err)) {
+ if (mmsvc_core_msg_json_deserialize_len("handle", client->recvMsg + client->msg_offset, &parse_len, &handle, &err))
+ LOGD("cmd: %d len: %d Message: %s", cmd, len, client->recvMsg);
+ switch (cmd) {
+ case API_CREATE:
+ if (mmsvc_core_msg_json_deserialize_len("client", client->recvMsg + client->msg_offset, &parse_len, &api_client, &err)) {
+ client->api_client = api_client;
+ client->ch[MUSED_CHANNEL_MSG].module = mmsvc_core_module_load(api_client);
+ client->ch[MUSED_CHANNEL_DATA].queue = g_queue_new();
+ g_mutex_init(&client->ch[MUSED_CHANNEL_DATA].mutex);
+ g_cond_init(&client->ch[MUSED_CHANNEL_DATA].cond);
+ LOGD("client fd: %d module: %p",
+ client->ch[MUSED_CHANNEL_MSG].fd,
+ client->ch[MUSED_CHANNEL_MSG].module);
+ mmsvc_core_module_dll_symbol(cmd, client);
+ break;
+ }
+ case API_DESTROY:
+ LOGD("DESTROY");
+ mmsvc_core_module_dll_symbol(cmd, client);
+ g_queue_free(client->ch[MUSED_CHANNEL_DATA].queue);
+ g_mutex_clear(&client->ch[MUSED_CHANNEL_DATA].mutex);
+ g_cond_clear(&client->ch[MUSED_CHANNEL_DATA].cond);
+ mmsvc_core_module_close(client);
+ mmsvc_core_worker_exit(client);
+ break;
+ default:
+ LOGD("[default] client->module: %p", client->ch[MUSED_CHANNEL_MSG].module);
+ mmsvc_core_module_dll_symbol(cmd, client);
+ break;
+ }
+ } else {
+ LOGE("Parsing status : %d", err);
+ break;
+ }
+
+ if (parse_len == 0)
+ break;
+
+ client->msg_offset += parse_len;
+ parse_len = len - parse_len;
+ }
+ }
+ }
+
+ LOGD("Leave");
+ return NULL;
+}
+
+static gpointer _mmsvc_core_ipc_data_worker(gpointer data)
+{
+ int recvLen = 0;
+ int currLen = 0;
+ int fd = (int) data;
+ Client client = NULL;
+ char *recvBuff = NULL;
+ int allocSize = 0;
+
+ g_return_val_if_fail(fd > 0, NULL);
+
+ while(1) {
+ if (!recvBuff) {
+ allocSize = MM_MSG_MAX_LENGTH;
+ recvBuff = g_new(char, allocSize);
+ }
+ if (!recvBuff) {
+ LOGE("Out of memory");
+ break;
+ }
+ recvLen = mmsvc_core_ipc_recv_msg(fd, recvBuff + currLen);
+ currLen += recvLen;
+ LOGD("buff %p, recvLen %d, currLen %d, allocSize %d",
+ recvBuff, recvLen, currLen, allocSize);
+ if (recvLen <= 0) {
+ LOGE("recv : %s (%d)", strerror(errno), errno);
+ break;
+ } else {
+ if (client) {
+ RecvData_t *qData;
+ while ((qData = _mmsvc_core_ipc_new_qdata(&recvBuff, currLen, &allocSize))
+ != NULL) {
+ int qDataSize = qData->header.size + sizeof(RecvDataHead_t);
+ if (currLen > qDataSize) {
+ allocSize = allocSize - qDataSize;
+ char *newBuff = g_new(char, allocSize);
+ memcpy(newBuff, recvBuff + qDataSize, currLen - qDataSize);
+ recvBuff = newBuff;
+ }
+ g_queue_push_tail(client->ch[MUSED_CHANNEL_DATA].queue, qData);
+ g_cond_signal(&client->ch[MUSED_CHANNEL_DATA].cond);
+
+ currLen = currLen - qDataSize;
+ if (!currLen)
+ break;
+ }
+ if (!currLen) {
+ recvBuff = NULL;
+ } else if (allocSize < MM_MSG_MAX_LENGTH + currLen) {
+ allocSize = MM_MSG_MAX_LENGTH + currLen;
+ recvBuff = g_renew(char, recvBuff, allocSize);
+ }
+ } else {
+ int data = 0;
+ if (mmsvc_core_msg_json_deserialize("client_addr", recvBuff, &data, NULL)) {
+ client = (Client)data;
+ if (client) {
+ client->ch[MUSED_CHANNEL_DATA].p_gthread = g_thread_self();
+ }
+ }
+ MMSVC_FREE(recvBuff);
+ recvBuff = NULL;
+ currLen = 0;
+ }
+ }
+ }
+
+ MMSVC_FREE(recvBuff);
+
+ LOGD("Leave");
+ return NULL;
+}
+
+gboolean mmsvc_core_ipc_job_function(mmsvc_core_workqueue_job_t *job)
+{
+ LOGD("Enter");
+ Client client = NULL;
+
+ g_return_val_if_fail(job != NULL, FALSE);
+
+ client = (Client) job->user_data;
+ g_return_val_if_fail(client != NULL, FALSE);
+
+ LOGD("[%p] client->fd : %d", client, client->ch[MUSED_CHANNEL_MSG].fd);
+
+ client->ch[MUSED_CHANNEL_MSG].p_gthread = g_thread_new(NULL, _mmsvc_core_ipc_dispatch_worker, (gpointer)client);
+ if (!client->ch[MUSED_CHANNEL_MSG].p_gthread) {
+ LOGE("Error - g_thread_new");
+ return FALSE;
+ }
+
+ MMSVC_FREE(job);
+
+ LOGD("Leave");
+ return TRUE;
+}
+
+gboolean mmsvc_core_ipc_data_job_function(mmsvc_core_workqueue_job_t *job)
+{
+ LOGD("Enter");
+ int fd;
+
+ g_return_val_if_fail(job != NULL, FALSE);
+
+ fd = (int) job->user_data;
+ g_return_val_if_fail(fd > 0, FALSE);
+
+ LOGD("data channel fd : %d", fd);
+
+ g_thread_new(NULL, _mmsvc_core_ipc_data_worker, (gpointer)fd);
+#if 0
+ if (!client->p_gthread) {
+ LOGE("Error - g_thread_new");
+ return FALSE;
+ }
+#endif
+ MMSVC_FREE(job);
+
+ LOGD("Leave");
+ return TRUE;
+}
+
+int mmsvc_core_ipc_send_msg(int sock_fd, const char *msg)
+{
+ int ret = -1;
+
+ g_return_val_if_fail(msg != NULL, ret);
+
+ if ((ret = send(sock_fd, msg, strlen(msg), 0)) < 0)
+ LOGE("send msg failed");
+
+ return ret;
+}
+
+int mmsvc_core_ipc_recv_msg(int sock_fd, char *msg)
+{
+ int ret = -1;
+
+ g_return_val_if_fail(msg != NULL, ret);
+
+ if ((ret = recv(sock_fd, msg, MM_MSG_MAX_LENGTH, 0)) < 0)
+ LOGE("received msg");
+
+ return ret;
+}
+
+int mmsvc_core_ipc_push_data(int sock_fd, const char *data, int size, int data_id)
+{
+ int ret = -1;
+ RecvDataHead_t header;
+ g_return_val_if_fail(data != NULL, ret);
+
+ header.marker = MUSED_DATA_HEAD;
+ header.id = data_id;
+ header.size = size;
+
+ if ((ret = send(sock_fd, &header, sizeof(RecvDataHead_t), 0)) < 0)
+ LOGE("send msg failed");
+ if ((ret += send(sock_fd, data, size, 0)) < 0)
+ LOGE("send msg failed");
+
+ return ret;
+}
+
+static RecvData_t *_mmsvc_core_ipc_new_qdata(char **recvBuff, int recvSize, int *allocSize)
+{
+ int qDataSize;
+ RecvData_t *qData = (RecvData_t *)*recvBuff;
+ g_return_if_fail(recvBuff);
+
+ if (qData->header.marker != MUSED_DATA_HEAD) {
+ LOGE("Invalid data header");
+ return NULL;
+ }
+ qDataSize = qData->header.size + sizeof(RecvDataHead_t);
+ if (qDataSize > recvSize) {
+ LOGD("not complated recv");
+ if (qDataSize > *allocSize) {
+ LOGD("Realloc %d -> %d", *allocSize, qDataSize);
+ *allocSize = qDataSize;
+ *recvBuff = g_renew(char, *recvBuff, *allocSize);
+ }
+ return NULL;
+ }
+
+ return qData;
+}
+
+void mmsvc_core_ipc_delete_data(char *data)
+{
+ RecvData_t *qData;
+ g_return_if_fail(data);
+
+ qData = (RecvData_t *)(data - sizeof(RecvDataHead_t));
+ if (qData && qData->header.marker == MUSED_DATA_HEAD) {
+ MMSVC_FREE(qData);
+ }
+}
+
+char *mmsvc_core_ipc_get_data(Client client)
+{
+ RecvData_t *qData;
+ char *rawData;
+ channel_info *ch;
+ gint64 end_time = g_get_monotonic_time() + 100 * G_TIME_SPAN_MILLISECOND;
+ g_return_val_if_fail(client, NULL);
+ ch = &client->ch[MUSED_CHANNEL_DATA];
+
+ g_mutex_lock(&ch->mutex);
+ if (g_queue_is_empty(ch->queue))
+ g_cond_wait_until(&ch->cond, &ch->mutex, end_time);
+ g_mutex_unlock(&ch->mutex);
+
+ qData = g_queue_pop_head(ch->queue);
+ if (qData) {
+ rawData = (char *)qData + sizeof(RecvDataHead_t);
+ return rawData;
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mmsvc_core_internal.h"
+#include "mmsvc_core_log.h"
+#include <ucontext.h>
+
+/* Signals */
+#define RECEIVED_SIG_RESTART 0x0001
+#define RECEIVED_SIG_EXIT 0x0002
+#define RECEIVED_SIG_SHUTDOWN 0x0004
+#define RECEIVED_SIG_SEGV 0x0008
+#define RECEIVED_SIG_TERMINATE 0x0010
+#define RECEIVED_SIG_XCPU 0x0020
+#define RECEIVED_SIG_TERM_OTHER 0x0040
+#define RECEIVED_SIG_ABORT 0x0080
+#define RECEIVED_SIG_EVENT 0x0100
+#define RECEIVED_SIG_CHLD 0x0200
+#define RECEIVED_SIG_ALRM 0x0400
+#define TUNABLE_CALLER_DEPTH 32
+#define MSG_LENGTH 1024 * 1024
+#define U32BITS 0xffffffff
+#define FILESYSTEMIO_MAX_DUPFDS 512
+
+static mmsvc_core_log_t *g_mused_log = NULL;
+volatile unsigned int received_signal_flags = 0;
+
+static void _mmsvc_core_log_sig_child(int signo);
+static char *_mmsvc_core_log_prepare_core(void);
+static void _mmsvc_core_log_sig_abort(int signo);
+static void _mmsvc_core_log_sig_terminate(int signo);
+static void _mmsvc_core_log_sig_restart(int signo);
+static int _mmsvc_core_log_init_signal_set(void);
+static void _mmsvc_core_log_init_signals(void);
+static int _mmsvc_core_log_fd_set_block(int fd);
+static void _mmsvc_core_log_sigaction(int signo, siginfo_t *si, void *arg);
+static void _mmsvc_core_log_set_log_fd(void);
+static void _mmsvc_core_log_init_instance(void (*log)(char *), void (*fatal)(char *), void (*set_module_value) (int, GModule *, gboolean), gboolean(*get_module_opened) (int), GModule * (*get_module_value) (int));
+static void _mmsvc_core_log_monitor(char *msg);
+static void _mmsvc_core_log_fatal(char *msg);
+static int _mmsvc_core_log_init_signal_set(void);
+static void _mmsvc_core_log_set_module_value(int index, GModule *module, gboolean value);
+static gboolean _mmsvc_core_log_get_module_opened(int index);
+static GModule *_mmsvc_core_log_get_module_value(int index);
+
+static void _mmsvc_core_log_sig_child(int signo)
+{
+ received_signal_flags |= RECEIVED_SIG_CHLD;
+
+ if (SIG_ERR == signal(SIGCHLD, _mmsvc_core_log_sig_child))
+ LOGE("SIGCHLD handler: %s", strerror(errno));
+}
+
+static char *_mmsvc_core_log_prepare_core(void)
+{
+ int result = chdir("/");
+ static char dir[256];
+
+ memset(dir, '\0', sizeof(dir));
+ snprintf(dir, sizeof(dir)-1, "%s/mused_%lu", MUSED_DIR, (unsigned long) getpid());
+
+ if (mkdir(dir, 0700) < 0) {
+ LOGE("unable to create directory '%s' for coredump: %s", dir, strerror(errno));
+ } else {
+ result = chdir(dir);
+ LOGD("result = %d", result);
+ }
+
+ return dir;
+}
+
+static void _mmsvc_core_log_sig_abort(int signo)
+{
+ received_signal_flags |= RECEIVED_SIG_ABORT;
+
+ if (SIG_ERR == signal(SIGABRT, SIG_DFL))
+ LOGE("SIGABRT andler: %s", strerror(errno));
+
+ LOGD("mused received SIGABRT signal, generating core file in %s", _mmsvc_core_log_prepare_core());
+ abort();
+}
+
+static void _mmsvc_core_log_sig_terminate(int signo)
+{
+ if (signo == SIGSEGV || signo == SIGXCPU || signo == SIGBUS) {
+ if (signo == SIGXCPU) {
+ received_signal_flags |= RECEIVED_SIG_XCPU;
+ } else {
+ received_signal_flags |= RECEIVED_SIG_SEGV;
+ }
+
+ LOGD("mused terminating (%d)", signo);
+
+ } else if (signo == SIGTERM) {
+ received_signal_flags |= RECEIVED_SIG_TERMINATE;
+
+ } else {
+ received_signal_flags |= RECEIVED_SIG_TERM_OTHER;
+ }
+
+ if (SIG_ERR == signal(signo, SIG_IGN))
+ LOGE("handler for %d: %s", signo, strerror(errno));
+}
+
+static void _mmsvc_core_log_sig_restart(int signo)
+{
+ received_signal_flags |= RECEIVED_SIG_RESTART;
+
+ if (SIG_ERR == signal(SIGHUP, _mmsvc_core_log_sig_restart))
+ LOGE("SIGHUP andler: %s", strerror(errno));
+}
+
+static void _mmsvc_core_log_signals_handle_event(int signo)
+{
+ received_signal_flags |= RECEIVED_SIG_EVENT;
+
+ if (SIG_ERR == signal(SIGUSR2, _mmsvc_core_log_signals_handle_event))
+ LOGE(" SIGUSR2 handler: %s", strerror(errno));
+}
+
+static int _mmsvc_core_log_init_signal_set(void)
+{
+ sigset_t mmsvc_core_log_sig_set;
+
+ sigemptyset(&mmsvc_core_log_sig_set);
+
+ sigaddset(&mmsvc_core_log_sig_set, SIGCHLD);
+ sigaddset(&mmsvc_core_log_sig_set, SIGINT);
+ sigaddset(&mmsvc_core_log_sig_set, SIGQUIT);
+ sigaddset(&mmsvc_core_log_sig_set, SIGILL);
+ sigaddset(&mmsvc_core_log_sig_set, SIGABRT);
+ sigaddset(&mmsvc_core_log_sig_set, SIGFPE);
+ sigaddset(&mmsvc_core_log_sig_set, SIGSEGV);
+ sigaddset(&mmsvc_core_log_sig_set, SIGALRM);
+ sigaddset(&mmsvc_core_log_sig_set, SIGTERM);
+ sigaddset(&mmsvc_core_log_sig_set, SIGHUP);
+ sigaddset(&mmsvc_core_log_sig_set, SIGUSR2);
+ sigaddset(&mmsvc_core_log_sig_set, SIGSTKFLT);
+ sigaddset(&mmsvc_core_log_sig_set, SIGIO);
+ sigaddset(&mmsvc_core_log_sig_set, SIGBUS);
+
+ if (SIG_ERR == signal(SIGCHLD, _mmsvc_core_log_sig_child) || SIG_ERR == signal(SIGHUP, _mmsvc_core_log_sig_restart)
+ || SIG_ERR == signal(SIGINT, _mmsvc_core_log_sig_terminate) || SIG_ERR == signal(SIGQUIT, _mmsvc_core_log_sig_terminate)
+ || SIG_ERR == signal(SIGILL, _mmsvc_core_log_sig_terminate) || SIG_ERR == signal(SIGFPE, _mmsvc_core_log_sig_terminate)
+ || SIG_ERR == signal(SIGABRT, _mmsvc_core_log_sig_abort) || SIG_ERR == signal(SIGSEGV, _mmsvc_core_log_sig_terminate)
+ || SIG_ERR == signal(SIGXCPU, _mmsvc_core_log_sig_terminate) || SIG_ERR == signal(SIGBUS, _mmsvc_core_log_sig_terminate)
+ || SIG_ERR == signal(SIGALRM, SIG_IGN) || SIG_ERR == signal(SIGTERM, _mmsvc_core_log_sig_terminate)
+ || SIG_ERR == signal(SIGURG, SIG_IGN) || SIG_ERR == signal(SIGSTKFLT, _mmsvc_core_log_sig_terminate)
+ || SIG_ERR == signal(SIGIO, SIG_IGN) || SIG_ERR == signal(SIGUSR2, _mmsvc_core_log_signals_handle_event)
+ || 0 > sigprocmask(SIG_UNBLOCK, &mmsvc_core_log_sig_set, NULL)) {
+ LOGE("signal : %s", strerror(errno));
+ }
+
+ return 0;
+}
+
+static void _mmsvc_core_log_init_signals(void)
+{
+ struct sigaction action;
+
+ _mmsvc_core_log_init_signal_set();
+
+ memset(&action, 0, sizeof(sigaction));
+ sigemptyset(&action.sa_mask);
+ action.sa_sigaction = _mmsvc_core_log_sigaction;
+ action.sa_flags = SA_RESTART | SA_SIGINFO;
+
+ sigaction(SIGSEGV, &action, NULL);
+ sigaction(SIGBUS, &action, NULL);
+ sigaction(SIGXCPU, &action, NULL);
+ sigaction(SIGUSR1, &action, NULL);
+}
+
+static int _mmsvc_core_log_fd_set_block(int fd)
+{
+ int flags;
+ int ret;
+
+ flags = fcntl(fd, F_GETFL);
+ ret = fcntl(fd, F_SETFL, flags & (U32BITS ^ O_NONBLOCK));
+
+ return ret;
+}
+
+static void _mmsvc_core_log_sigaction(int signo, siginfo_t *si, void *arg)
+{
+ void *trace[TUNABLE_CALLER_DEPTH];
+ int tracesize;
+
+ g_return_if_fail(si != NULL);
+ g_return_if_fail(arg != NULL);
+
+ _mmsvc_core_log_sig_terminate(signo);
+
+ LOGE("----------BEGIN MUSED DYING MESSAGE----------");
+
+ tracesize = backtrace(trace, TUNABLE_CALLER_DEPTH);
+ if (tracesize < 0)
+ LOGE("backtrace error: %s", strerror(errno));
+
+ #if defined(REG_EIP)
+ int i;
+ char **strings = NULL;
+ /* overwrite sigaction with caller's address for x86*/
+ ucontext_t *uctxt = NULL;
+ uctxt = (ucontext_t *) arg;
+
+ if (!uctxt) {
+ LOGE("Error - null uctxt");
+ return;
+ }
+
+ trace[1] = (void *) uctxt->uc_mcontext.gregs[REG_EIP];
+ strings = backtrace_symbols(trace, tracesize);
+ if (strings == NULL)
+ LOGE("backtrace_symbols error: %s", strerror(errno));
+
+ /* skip the first stack frame because it just points here. */
+ for (i = 1; i < tracesize; ++i) {
+ LOGE("[%u] %s", i-1, strings[i]);
+ if (g_mused_log)
+ g_mused_log->fatal(strings[i]);
+ }
+ #endif
+
+ LOGE("----------END MUSED DYING MESSAGE----------");
+
+ LOGE("exit(0) - caught segfault at address %p", si->si_addr);
+
+ exit(0);
+}
+
+static void _mmsvc_core_log_set_log_fd(void)
+{
+ LOGD("Enter");
+
+ g_return_if_fail(g_mused_log != NULL);
+
+ g_mused_log->log_fd = open(LOGFILE, O_CREAT | O_APPEND | O_WRONLY | O_NONBLOCK, 0666);
+ if (g_mused_log->log_fd < 0) {
+ LOGE("error: %s is not a regular file", LOGFILE);
+ return;
+ }
+
+ if (fcntl(g_mused_log->log_fd, F_SETFD, FD_CLOEXEC) < 0)
+ LOGE("unable to set CLO_EXEC on log fd %d: %s", g_mused_log->log_fd, strerror(errno));
+
+ (void) _mmsvc_core_log_fd_set_block(g_mused_log->log_fd);
+
+ LOGD("Leave");
+}
+
+static void _mmsvc_core_log_init_instance(void (*log)(char *), void (*fatal)(char *), void (*set_module_value) (int, GModule *, gboolean), gboolean(*get_module_opened) (int), GModule * (*get_module_value) (int))
+{
+ g_return_if_fail(log != NULL);
+ g_return_if_fail(fatal != NULL);
+ g_return_if_fail(g_mused_log == NULL);
+
+ int idx = 0;
+
+ g_mused_log = calloc(1, sizeof(*g_mused_log));
+ g_mused_log->buf = NULL;
+ g_mused_log->len = 0;
+ g_mused_log->log = log;
+ g_mused_log->fatal = fatal;
+ g_mused_log->set_module_value = set_module_value;
+ g_mused_log->get_module_opened = get_module_opened;
+ g_mused_log->get_module_value = get_module_value;
+ g_mused_log->timer = g_timer_new();
+ g_mused_log->count = 0;
+ g_timer_stop(g_mused_log->timer);
+ for (idx = 0; idx < MMSVC_CLIENT_MAX; idx++) {
+ g_mused_log->module_opened[idx] = false;
+ }
+}
+
+static void _mmsvc_core_log_monitor(char *msg)
+{
+ g_return_if_fail(msg != NULL);
+ g_return_if_fail(g_mused_log != NULL);
+
+ if (g_mused_log->count != 0)
+ g_timer_continue(g_mused_log->timer);
+
+ if (g_mused_log->log_fd < 0) {
+ LOGE("Error - log fd");
+ return;
+ }
+
+ if (write(g_mused_log->log_fd, msg, strlen(msg)) != strlen(msg)) {
+ LOGE("There was an error writing to testfile");
+ } else {
+ if (write(g_mused_log->log_fd, "\n", 1) == 1)
+ LOGD("write %s", msg);
+ }
+
+ if (g_mused_log->count != 0)
+ g_timer_stop(g_mused_log->timer);
+}
+
+static void _mmsvc_core_log_fatal(char *msg)
+{
+ if (!msg) {
+ LOGE("Error - null msg");
+ return;
+ }
+
+ _mmsvc_core_log_monitor(msg);
+
+ exit(-1);
+}
+
+static void _mmsvc_core_log_set_module_value(int index, GModule *module, gboolean value)
+{
+ g_return_if_fail(g_mused_log != NULL);
+ g_return_if_fail(module != NULL);
+
+ g_mused_log->module_opened[index] = value;
+ g_mused_log->module[index] = module;
+ LOGD("module: %p", g_mused_log->module[index]);
+}
+
+static gboolean _mmsvc_core_log_get_module_opened(int index)
+{
+ g_return_val_if_fail(g_mused_log != NULL, false);
+
+ return g_mused_log->module_opened[index];
+}
+
+static GModule *_mmsvc_core_log_get_module_value(int index)
+{
+ g_return_val_if_fail(g_mused_log != NULL, NULL);
+
+ LOGD("module: %p", g_mused_log->module[index]);
+ return g_mused_log->module[index];
+}
+
+mmsvc_core_log_t *mmsvc_core_log_get_instance(void)
+{
+ if (g_mused_log == NULL)
+ _mmsvc_core_log_init_instance(_mmsvc_core_log_monitor, _mmsvc_core_log_fatal, _mmsvc_core_log_set_module_value,
+ _mmsvc_core_log_get_module_opened, _mmsvc_core_log_get_module_value);
+
+ return g_mused_log;
+}
+
+void mmsvc_core_log_init(void)
+{
+ LOGD("Enter");
+
+ if (g_mused_log == NULL)
+ _mmsvc_core_log_init_instance(_mmsvc_core_log_monitor, _mmsvc_core_log_fatal, _mmsvc_core_log_set_module_value,
+ _mmsvc_core_log_get_module_opened, _mmsvc_core_log_get_module_value);
+
+ _mmsvc_core_log_set_log_fd();
+ _mmsvc_core_log_init_signals();
+
+ LOGD("Leave");
+}
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mmsvc_core_config.h"
+#include "mmsvc_core_log.h"
+#include "mmsvc_core_internal.h"
+#include "mmsvc_core_module.h"
+#include "mmsvc_core_private.h"
+
+GModule *mmsvc_core_module_load(int api_client)
+{
+ GModule *module = NULL;
+
+ if (mmsvc_core_log_get_instance()->get_module_opened(api_client) == false) {
+ LOGD("api client : %d", api_client);
+ module = g_module_open(mmsvc_core_config_get_instance()->get_path(api_client), G_MODULE_BIND_LAZY);
+
+ if (!module) {
+ LOGE("%s", g_module_error());
+ return NULL;
+ } else {
+ mmsvc_core_log_get_instance()->set_module_value(api_client, module, true);
+ }
+ } else if (mmsvc_core_log_get_instance()->get_module_opened(api_client) == true) {
+ module = mmsvc_core_log_get_instance()->get_module_value(api_client);
+ LOGW("already module is opened: %p", module);
+ }
+
+ return module;
+}
+
+void mmsvc_core_module_dll_symbol(int cmd, Client client)
+{
+ MMSVC_MODULE_DispatchFunc *dispatcher = NULL;
+
+ g_return_if_fail(client->ch[MUSED_CHANNEL_MSG].module != NULL);
+
+ LOGD("cmd: %d\t client->module: %p", cmd, client->ch[MUSED_CHANNEL_MSG].module);
+ g_module_symbol(client->ch[MUSED_CHANNEL_MSG].module, DISPATCHER, (gpointer *)&dispatcher);
+
+ if (dispatcher && dispatcher[cmd]) {
+ LOGD("dispatcher: %p", dispatcher);
+ dispatcher[cmd](client);
+ } else {
+ LOGE("error - dispatcher");
+ return;
+ }
+}
+
+gboolean mmsvc_core_module_close(Client client)
+{
+ g_return_val_if_fail(client != NULL, FALSE);
+
+ mmsvc_core_log_get_instance()->set_module_value(client->api_client, client->ch[MUSED_CHANNEL_MSG].module, false);
+
+ LOGD("Closing module %s", g_module_name(client->ch[MUSED_CHANNEL_MSG].module));
+ if (!g_module_close(client->ch[MUSED_CHANNEL_MSG].module)) {
+ LOGE("Couldn't close module %s: %s", g_module_name(client->ch[MUSED_CHANNEL_MSG].module), g_module_error());
+ return FALSE;
+ }
+
+ return TRUE;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "json.h"
+#include "json_tokener.h"
+#include "mmsvc_core_msg_json.h"
+#include "mmsvc_core_internal.h"
+
+static json_object *_mmsvc_core_msg_json_find_obj(json_object * jobj, char *find_key)
+{
+ size_t key_len = 0;
+
+ g_return_val_if_fail(jobj != NULL, NULL);
+
+ g_return_val_if_fail(find_key != NULL, NULL);
+
+ key_len = strlen(find_key);
+
+ json_object_object_foreach(jobj, key, val) {
+ if (strlen(key) == key_len && !memcmp(key, find_key, key_len))
+ return val;
+ }
+
+ return NULL;
+}
+
+static void _mmsvc_core_msg_json_set_error(mused_msg_parse_err_e *err, int jerr)
+{
+ if (err != NULL) {
+ switch (jerr) {
+ case json_tokener_success:
+ *err = MUSED_MSG_PARSE_ERROR_NONE;
+ break;
+ case json_tokener_continue:
+ *err = MUSED_MSG_PARSE_ERROR_CONTINUE;
+ break;
+ default:
+ *err = MUSED_MSG_PARSE_ERROR_OTHER;
+ break;
+ }
+ }
+}
+
+static json_object *_mmsvc_core_msg_json_tokener_parse_len(const char *str, int *len, mused_msg_parse_err_e *err)
+{
+ struct json_tokener *tok;
+ struct json_object *obj;
+
+ g_return_val_if_fail(str != NULL, NULL);
+ g_return_val_if_fail(len != NULL, NULL);
+
+ tok = json_tokener_new();
+
+ g_return_val_if_fail(tok != NULL, NULL);
+
+ obj = json_tokener_parse_ex(tok, str, *len);
+ g_return_val_if_fail(obj != NULL, NULL);
+
+ *len = tok->char_offset;
+
+ if (tok->err != json_tokener_success) {
+ LOGE("Json Error(%d) : %s", tok->err, json_tokener_error_desc(tok->err));
+ json_object_put(obj);
+ obj = NULL;
+ }
+ _mmsvc_core_msg_json_set_error(err, tok->err);
+
+ json_tokener_free(tok);
+ return obj;
+}
+
+static void _mmsvc_core_msg_json_factory_args(json_object *jobj, va_list ap)
+{
+ int type;
+ char *name;
+
+ while ((type = va_arg(ap, int)) != 0) {
+ name = va_arg(ap, char *);
+ LOGD("name: %s ", name);
+ switch (type) {
+ case MUSED_TYPE_INT:
+ json_object_object_add(jobj, name, json_object_new_int(va_arg(ap, int)));
+ break;
+ case MUSED_TYPE_DOUBLE:
+ json_object_object_add(jobj, name, json_object_new_double(va_arg(ap, double)));
+ break;
+ case MUSED_TYPE_STRING:
+ json_object_object_add(jobj, name, json_object_new_string(va_arg(ap, char *)));
+ break;
+ case MUSED_TYPE_ARRAY:
+ {
+ int len = va_arg(ap, int);
+ int *value = va_arg(ap, int *);
+ int i;
+ json_object *jarr = json_object_new_array();
+
+ for (i = 0; i < len; i++)
+ json_object_array_add(jarr, json_object_new_int(value[i]));
+ json_object_object_add(jobj, name, jarr);
+ }
+ break;
+ default:
+ LOGE("Unexpected type");
+ }
+ }
+}
+
+char *mmsvc_core_msg_json_factory_new(int api, const char *arg_name, int arg, ...)
+{
+ json_object *jobj;
+ const char *jsonMsg;
+ char *sndMsg;
+ va_list ap;
+
+ jobj = json_object_new_object();
+
+ g_return_val_if_fail(jobj != NULL, NULL);
+
+ json_object_object_add(jobj, "api", json_object_new_int(api));
+ if (arg_name)
+ json_object_object_add(jobj, arg_name, json_object_new_int(arg));
+ else
+ LOGE("Error - null arg_name");
+
+ va_start(ap, arg);
+ _mmsvc_core_msg_json_factory_args(jobj, ap);
+ va_end(ap);
+
+ jsonMsg = json_object_to_json_string(jobj);
+ sndMsg = g_strdup(jsonMsg);
+ LOGD("json msg : %s\n", sndMsg);
+
+ json_object_put(jobj);
+
+ return sndMsg;
+}
+
+void mmsvc_core_msg_json_factory_free(char *msg)
+{
+ if (msg)
+ MMSVC_FREE(msg);
+}
+
+gboolean mmsvc_core_msg_json_deserialize(char *key, char* buf, void *data, mused_msg_parse_err_e *err)
+{
+ int len = 0;
+
+ g_return_val_if_fail(buf != NULL, FALSE);
+ g_return_val_if_fail(data != NULL, FALSE);
+
+ len = strlen(buf);
+ return mmsvc_core_msg_json_deserialize_len(key, buf, &len, data, err);
+}
+
+gboolean mmsvc_core_msg_json_deserialize_len(char *key, char* buf, int *parse_len, void *data, mused_msg_parse_err_e *err)
+{
+ int type;
+ json_object *val, *jobj;
+
+ g_return_val_if_fail(key != NULL, FALSE);
+ g_return_val_if_fail(buf != NULL, FALSE);
+ g_return_val_if_fail(data != NULL, FALSE);
+ g_return_val_if_fail(parse_len != NULL, FALSE);
+
+ jobj = _mmsvc_core_msg_json_tokener_parse_len(buf, parse_len, err);
+ g_return_val_if_fail(jobj != NULL, FALSE);
+
+ val = _mmsvc_core_msg_json_find_obj(jobj, key);
+ if (!val) {
+ LOGE("\"%s\" key is not founded", key);
+ return FALSE;
+ }
+
+ type = json_object_get_type(val);
+ switch (type) {
+ case json_type_null:
+ LOGD("json_type_null\n");
+ break;
+ case json_type_boolean:
+ LOGD("json_type_boolean (%s) value: %d", key, json_object_get_boolean(val));
+ break;
+ case json_type_double:
+ *(double *)data = json_object_get_double(val);
+ LOGD("json_type_double (%s) value: %p", key, (double *)data);
+ break;
+ case json_type_int:
+ *(int *)data = json_object_get_int(val);
+ LOGD("json_type_int (%s) value: %p", key, (int *)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);
+ int i, len;
+ int *int_data = (int *)data;
+ len = json_object_array_length(val);
+ for (i = 0; i < len; i++)
+ int_data[i] = json_object_get_int(json_object_array_get_idx(val, i));
+ break;
+ }
+ json_object_put(jobj);
+ return TRUE;
+}
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mmsvc_core.h"
+#include "mmsvc_core_internal.h"
+#include "mmsvc_core_config.h"
+#include "mmsvc_core_log.h"
+#include "mmsvc_core_tool.h"
+
+static void _mmsvc_core_server_setup_syslog(void);
+extern int mmsvc_core_run();
+
+static void _mmsvc_core_server_setup_syslog(void)
+{
+ int flags = LOG_CONS|LOG_NDELAY|LOG_PID;
+ if (isatty(1))
+ flags |= LOG_PERROR;
+
+ openlog("mused", flags, LOG_DAEMON);
+ LOGD("openlog - mused");
+}
+
+int main(int argc, char **argv)
+{
+ int result;
+ pid_t pid, sid;
+
+ _mmsvc_core_server_setup_syslog();
+ mmsvc_core_log_init();
+ mmsvc_core_config_init();
+
+ if (argc > 1 && argv)
+ mmsvc_core_tool_parse_params(argc, argv);
+
+ /* daemon_init */
+ if (getpid() == 1) {
+ LOGE("already a daemon");
+ exit(0);
+ }
+
+ if ((pid = fork()) < 0) {
+ LOGE("Could not fork child.");
+ exit(0);
+ } else if (pid != 0) {
+ LOGD("PID : %d, PID CLOSE!!", pid);
+ exit(0);
+ }
+
+ /* create new session */
+ sid = setsid();
+ if (sid < 0) {
+ LOGE("sid SID : %d, PID CLOSE!!", pid);
+ exit(0);
+ }
+
+ /* Change the file mode mask */
+ umask(0);
+
+ result = chdir("/");
+ LOGD("result = %d", result);
+
+ return mmsvc_core_run();
+}
--- /dev/null
+/*
+ * mmsvc-core
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: YoungHun Kim <yh8004.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "mmsvc_core_internal.h"
+#include "mmsvc_core_log.h"
+#include "mmsvc_core_tool.h"
+#include <fts.h>
+
+#define VERSION "0.0.1"
+
+static int _mmsvc_core_tool_getopt(int argc, char **argv, const char *opts);
+
+int mmsvc_tool_optind = 1;
+int mmsvc_tool_optopt;
+char *mmsvc_tool_optarg;
+
+static const char *pid_file = NULL;
+static const char *out_file = NULL;
+static const char *err_file = NULL;
+static const char *lock_file = NULL;
+static bool be_verbose = FALSE;
+static const char *user = NULL;
+static char **mmsvc_cmd = NULL;
+static const char *cwd = "/";
+static int append = 0;
+
+static int _mmsvc_core_tool_getopt(int argc, char **argv, const char *opts)
+{
+ static int si = 1;
+ register int ri;
+ register char *cp;
+
+ if (si == 1) {
+ if (mmsvc_tool_optind >= argc ||argv[mmsvc_tool_optind][0] != '-' || argv[mmsvc_tool_optind][1] == '\0') {
+ return(EOF);
+ } else if (strcmp(argv[mmsvc_tool_optind], "--") == 0) {
+ mmsvc_tool_optind++;
+ return(EOF);
+ }
+ }
+ mmsvc_tool_optopt = ri = argv[mmsvc_tool_optind][si];
+ if (ri == ':' || (cp=strchr(opts, ri)) == NULL) {
+ if (argv[mmsvc_tool_optind][++si] == '\0') {
+ mmsvc_tool_optind++;
+ si = 1;
+ }
+ return('?');
+ }
+ if (*++cp == ':') {
+ if (argv[mmsvc_tool_optind][si+1] != '\0') {
+ mmsvc_tool_optarg = &argv[mmsvc_tool_optind++][si+1];
+ LOGD("%s", mmsvc_tool_optarg);
+ } else if (++mmsvc_tool_optind >= argc) {
+ LOGE(": option requires an argument - %c", ri);
+ si = 1;
+ return('?');
+ } else {
+ mmsvc_tool_optarg = argv[mmsvc_tool_optind++];
+ LOGD("%s", mmsvc_tool_optarg);
+ }
+ si = 1;
+ } else {
+ if (argv[mmsvc_tool_optind][++si] == '\0') {
+ si = 1;
+ mmsvc_tool_optind++;
+ }
+ mmsvc_tool_optarg = NULL;
+ }
+ LOGD("mmsvc_tool_optind: %d", mmsvc_tool_optind);
+ return(ri);
+}
+
+/**
+ * Parse the command-line parameters, setting the various globals that are affected by them.
+ *
+ * Parameters:
+ * argc - argument count, as passed to main()
+ * argv - argument vector, as passed to main()
+ */
+void mmsvc_core_tool_parse_params(int argc, char **argv)
+{
+ int opt;
+ int argsLeft;
+
+ LOGD("Enter");
+ opterr = 0;
+
+ while ((opt = _mmsvc_core_tool_getopt(argc, argv, "ac:u:p:vo:e:l:")) != -1) {
+ switch (opt) {
+ case 'a':
+ append = 1;
+ break;
+
+ case 'c':
+ cwd = mmsvc_tool_optarg;
+ break;
+
+ case 'p':
+
+ pid_file = mmsvc_tool_optarg;
+ break;
+
+ case 'v':
+ be_verbose = TRUE;
+ break;
+
+ case 'u':
+ user = mmsvc_tool_optarg;
+ break;
+
+ case 'o':
+ out_file = mmsvc_tool_optarg;
+ LOGD("out file: %s", out_file);
+ break;
+
+ case 'e':
+ err_file = mmsvc_tool_optarg;
+ break;
+
+ case 'l':
+ lock_file = mmsvc_tool_optarg;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ LOGD("mmsvc_tool_optind: %d", mmsvc_tool_optind);
+ argsLeft = argc - mmsvc_tool_optind;
+ LOGD("argsLeft : %d", argsLeft);
+
+ mmsvc_cmd = &argv[mmsvc_tool_optind];
+ LOGD("cmd: %s", *mmsvc_cmd);
+ LOGD("Leave");
+ return;
+}
+
+void mmsvc_core_tool_recursive_rmdir(const char *path)
+{
+ FTS *fts;
+ FTSENT *ftsent;
+
+ g_return_if_fail (path != NULL);
+
+ char *const paths[] = { (char *)path, NULL };
+
+ /* This means there can't be any autofs mounts yet, so this is the first time we're being run since a reboot. Clean out any stuff left in /Network from the reboot. */
+ fts = fts_open(paths, FTS_NOCHDIR | FTS_PHYSICAL, NULL);
+ if (fts != NULL) {
+ while ((ftsent = fts_read(fts)) != NULL) {
+ /* We only remove directories - if there are files, we assume they're there for a purpose.
+ * We remove directories after we've removed their children, so we want to process directories visited in post-order.*/
+ if (ftsent->fts_info == FTS_DP && ftsent->fts_level >= FTS_ROOTLEVEL)
+ rmdir(ftsent->fts_accpath);
+ }
+ fts_close(fts);
+ } else {
+ LOGE("Error - null fts");
+ return;
+ }
+}
--- /dev/null
+/**
+* Multithreaded work queue.
+* Copyright (c) 2012 Ronald Bennett Cemer
+* This software is licensed under the BSD license.
+* See the accompanying LICENSE.txt for details.
+*/
+
+#include "mmsvc_core_workqueue.h"
+#define WORK_THREAD_NUM 8
+#define LL_ADD(item, list) { \
+ item->prev = NULL; \
+ item->next = list; \
+ list = item; \
+}
+
+#define LL_REMOVE(item, list) { \
+ if (item->prev != NULL) item->prev->next = item->next; \
+ if (item->next != NULL) item->next->prev = item->prev; \
+ if (list == item) list = item->next; \
+ item->prev = item->next = NULL; \
+}
+
+static mmsvc_core_workqueue_workqueue_t *g_workqueue;
+
+static void *_mmsvc_core_workqueue_worker_function(void *ptr);
+static void _mmsvc_core_workqueue_shutdown(void);
+static void _mmsvc_core_workqueue_add_job(mmsvc_core_workqueue_job_t *job);
+static void _mmsvc_core_workqueue_init_instance(void (*shutdown)(void), void (*add_job)(mmsvc_core_workqueue_job_t *));
+
+static void *_mmsvc_core_workqueue_worker_function(void *ptr)
+{
+ LOGD("Enter");
+ mmsvc_core_workqueue_worker_t *worker = (mmsvc_core_workqueue_worker_t *) ptr;
+ mmsvc_core_workqueue_job_t *job;
+
+ while (1) {
+ /* Wait until we get notified. */
+ pthread_mutex_lock(&worker->workqueue->jobs_mutex);
+ while (worker->workqueue->waiting_jobs == NULL) {
+ /* If we're supposed to terminate, break out of our continuous loop. */
+ if (worker->terminate) {
+ LOGD("worker is terminated");
+ break;
+ }
+
+ pthread_cond_wait(&worker->workqueue->jobs_cond, &worker->workqueue->jobs_mutex);
+ }
+
+ /* If we're supposed to terminate, break out of our continuous loop. */
+ if (worker->terminate) {
+ LOGD("worker is terminated");
+ break;
+ }
+
+ job = worker->workqueue->waiting_jobs;
+ if (job != NULL)
+ LL_REMOVE(job, worker->workqueue->waiting_jobs);
+
+ pthread_mutex_unlock(&worker->workqueue->jobs_mutex);
+
+ /* If we didn't get a job, then there's nothing to do at this time. */
+ if (job == NULL)
+ continue;
+
+ /* Execute the job. */
+ job->job_function(job);
+ }
+
+ pthread_mutex_unlock(&worker->workqueue->jobs_mutex);
+ MMSVC_FREE(worker);
+
+ LOGD("Leave");
+
+ pthread_exit(NULL);
+}
+
+static void _mmsvc_core_workqueue_shutdown(void)
+{
+ mmsvc_core_workqueue_worker_t *worker = NULL;
+ g_return_if_fail(g_workqueue != NULL);
+ LOGD("Enter");
+
+ /* Set all workers to terminate. */
+ for (worker = g_workqueue->workers; worker != NULL; worker = worker->next) {
+ worker->terminate = 1;
+ }
+
+ /* Remove all workers and jobs from the work queue.
+ * wake up all workers so that they will terminate. */
+ pthread_mutex_lock(&g_workqueue->jobs_mutex);
+ g_workqueue->workers = NULL;
+ g_workqueue->waiting_jobs = NULL;
+ pthread_cond_broadcast(&g_workqueue->jobs_cond);
+ pthread_mutex_unlock(&g_workqueue->jobs_mutex);
+ LOGD("Leave");
+}
+
+static void _mmsvc_core_workqueue_add_job(mmsvc_core_workqueue_job_t *job)
+{
+ LOGD("Enter");
+ /* Add the job to the job queue, and notify a worker. */
+ pthread_mutex_lock(&g_workqueue->jobs_mutex);
+ LL_ADD(job, g_workqueue->waiting_jobs);
+ pthread_cond_signal(&g_workqueue->jobs_cond);
+ pthread_mutex_unlock(&g_workqueue->jobs_mutex);
+ LOGD("Leave");
+}
+
+static void _mmsvc_core_workqueue_init_instance(void (*shutdown)(void), void (*add_job)(mmsvc_core_workqueue_job_t *))
+{
+ g_return_if_fail(shutdown != NULL);
+ g_return_if_fail(add_job != NULL);
+ g_return_if_fail(g_workqueue != NULL);
+
+ g_workqueue->shutdown = shutdown;
+ g_workqueue->add_job = add_job;
+}
+
+mmsvc_core_workqueue_workqueue_t *mmsvc_core_workqueue_get_instance(void)
+{
+ LOGD("Enter");
+ if (g_workqueue == NULL)
+ mmsvc_core_workqueue_init(WORK_THREAD_NUM);
+
+ LOGD("Leave");
+ return g_workqueue;
+}
+
+int mmsvc_core_workqueue_init(int numWorkers)
+{
+ int i;
+ mmsvc_core_workqueue_worker_t *worker;
+ LOGD("Enter");
+ pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;
+ pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+ g_workqueue = calloc(1, sizeof(mmsvc_core_workqueue_workqueue_t));
+ if (!g_workqueue) {
+ LOGE("workqueue allocation failed");
+ return 1;
+ }
+
+ if (numWorkers < 1)
+ numWorkers = 1;
+ memset(g_workqueue, 0, sizeof(*g_workqueue));
+ memcpy(&g_workqueue->jobs_mutex, &blank_mutex, sizeof(g_workqueue->jobs_mutex));
+ memcpy(&g_workqueue->jobs_cond, &blank_cond, sizeof(g_workqueue->jobs_cond));
+
+ for (i = 0; i < numWorkers; i++) {
+ worker = malloc(sizeof(mmsvc_core_workqueue_worker_t));
+ if (worker == NULL) {
+ LOGE("Failed to allocate all workers");
+ return 1;
+ }
+ memset(worker, 0, sizeof(*worker));
+ worker->workqueue = g_workqueue;
+ if (pthread_create(&worker->thread, NULL, _mmsvc_core_workqueue_worker_function, (void *)worker)) {
+ LOGE("Failed to start all worker threads");
+ MMSVC_FREE(worker);
+ return 1;
+ }
+ LL_ADD(worker, worker->workqueue->workers);
+ }
+
+ _mmsvc_core_workqueue_init_instance(_mmsvc_core_workqueue_shutdown, _mmsvc_core_workqueue_add_job);
+
+ LOGD("Leave");
+ return 0;
+}
\ No newline at end of file