4 * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 #include <sys/socket.h>
26 #include "ctsvc_internal.h"
27 #include "ctsvc_socket.h"
28 #include "ctsvc_mutex.h"
29 #include "ctsvc_inotify.h"
31 static int __ctsvc_conn_refcnt = 0;
32 static int __ctsvc_sockfd = -1;
34 int ctsvc_socket_init(void)
37 struct sockaddr_un caddr;
39 if (0 < __ctsvc_conn_refcnt) {
40 __ctsvc_conn_refcnt++;
41 return CONTACTS_ERROR_NONE;
44 char sock_file[CTSVC_PATH_MAX_LEN] = {0};
45 snprintf(sock_file, sizeof(sock_file), CTSVC_SOCK_PATH"/%s", getuid(), CTSVC_SOCKET_FILE);
47 bzero(&caddr, sizeof(caddr));
48 caddr.sun_family = AF_UNIX;
49 snprintf(caddr.sun_path, sizeof(caddr.sun_path), "%s", sock_file);
51 __ctsvc_sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
52 RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC,
53 "socket() Fail(errno = %d)", errno);
55 ret = connect(__ctsvc_sockfd, (struct sockaddr *)&caddr, sizeof(caddr));
57 CTS_ERR("connect() Fail(errno = %d)", errno);
58 close(__ctsvc_sockfd);
60 return CONTACTS_ERROR_IPC;
63 __ctsvc_conn_refcnt++;
64 return CONTACTS_ERROR_NONE;
67 void ctsvc_socket_final(void)
69 if (1 < __ctsvc_conn_refcnt) {
70 CTS_DBG("socket ref count : %d", __ctsvc_conn_refcnt);
71 __ctsvc_conn_refcnt--;
74 else if (__ctsvc_conn_refcnt < 1) {
75 CTS_DBG("Please call connection API. socket ref count : %d", __ctsvc_conn_refcnt);
78 __ctsvc_conn_refcnt--;
80 close(__ctsvc_sockfd);
84 static inline int __ctsvc_safe_write(int fd, const char *buf, int buf_size)
88 ret = write(fd, buf+writed, buf_size);
101 static inline int __ctsvc_safe_read(int fd, char *buf, int buf_size)
103 int ret, read_size=0;
105 ret = read(fd, buf+read_size, buf_size);
118 #ifdef ENABLE_SIM_FEATURE
119 static int __ctsvc_socket_handle_return(int fd, ctsvc_socket_msg_s *msg)
124 ret = __ctsvc_safe_read(fd, (char *)msg, sizeof(ctsvc_socket_msg_s));
125 RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_read() Fail(errno = %d)", errno);
127 WARN_IF(CTSVC_SOCKET_MSG_TYPE_REQUEST_RETURN_VALUE != msg->type,
128 "Unknown Type(%d), ret=%d, attach_num= %d,"
129 "attach1 = %d, attach2 = %d, attach3 = %d, attach4 = %d",
130 msg->type, msg->val, msg->attach_num,
131 msg->attach_sizes[0],msg->attach_sizes[1],msg->attach_sizes[2],
132 msg->attach_sizes[3]);
134 RETVM_IF(CTSVC_SOCKET_MSG_REQUEST_MAX_ATTACH < msg->attach_num, CONTACTS_ERROR_IPC,
135 "Invalid msg(attach_num = %d)", msg->attach_num);
137 return CONTACTS_ERROR_NONE;
140 static void __ctsvc_remove_invalid_msg(int fd, int size)
143 char dummy[CTSVC_SOCKET_MSG_SIZE] = {0};
146 if (sizeof(dummy) < size) {
147 ret = read(fd, dummy, sizeof(dummy));
157 ret = read(fd, dummy, size);
169 int ctsvc_request_sim_import(int sim_slot_no)
172 ctsvc_socket_msg_s msg = {0};
175 RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC, "socket is not connected");
177 msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_IMPORT_SIM;
179 snprintf(src, sizeof(src), "%d", sim_slot_no);
181 msg.attach_sizes[0] = strlen(src);
183 ret = __ctsvc_safe_write(__ctsvc_sockfd, (char *)&msg, sizeof(msg));
184 RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Fail(errno = %d)", errno);
186 ret = __ctsvc_safe_write(__ctsvc_sockfd, src, msg.attach_sizes[0]);
187 RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Fail(errno = %d)", errno);
189 ret = __ctsvc_socket_handle_return(__ctsvc_sockfd, &msg);
190 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_socket_handle_return() Fail(%d)", ret);
191 CTS_DBG("attach_num = %d", msg.attach_num);
193 for (i=0;i<msg.attach_num;i++)
194 __ctsvc_remove_invalid_msg(__ctsvc_sockfd, msg.attach_sizes[i]);
199 int ctsvc_request_sim_get_initialization_status(int sim_slot_no, bool *completed)
202 ctsvc_socket_msg_s msg = {0};
203 char dest[CTSVC_SOCKET_MSG_SIZE] = {0};
206 RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC, "socket is not connected");
208 msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_SIM_INIT_COMPLETE;
210 snprintf(src, sizeof(src), "%d", sim_slot_no);
212 msg.attach_sizes[0] = strlen(src);
214 ret = __ctsvc_safe_write(__ctsvc_sockfd, (char *)&msg, sizeof(msg));
215 RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Fail(errno = %d)", errno);
217 ret = __ctsvc_safe_write(__ctsvc_sockfd, src, msg.attach_sizes[0]);
218 RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Fail(errno = %d)", errno);
220 ret = __ctsvc_socket_handle_return(__ctsvc_sockfd, &msg);
221 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_socket_handle_return() Fail(%d)", ret);
222 CTS_DBG("attach_num = %d", msg.attach_num);
224 ret = __ctsvc_safe_read(__ctsvc_sockfd, dest, msg.attach_sizes[0]);
225 RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_read() Fail(errno = %d)", errno);
232 CTS_INFO("sim init complete : %d", *completed);
237 #endif /* ENABLE_SIM_FEATURE */