Coding rule - Comment //=> /* */
[platform/core/pim/contacts-service.git] / common / ctsvc_socket.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20 #include <errno.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include <unistd.h>
24
25 #include "contacts.h"
26 #include "ctsvc_internal.h"
27 #include "ctsvc_socket.h"
28 #include "ctsvc_mutex.h"
29 #include "ctsvc_inotify.h"
30
31 static int __ctsvc_conn_refcnt = 0;
32 static int __ctsvc_sockfd = -1;
33
34 int ctsvc_socket_init(void)
35 {
36         int ret;
37         struct sockaddr_un caddr;
38
39         if (0 < __ctsvc_conn_refcnt) {
40                 __ctsvc_conn_refcnt++;
41                 return  CONTACTS_ERROR_NONE;
42         }
43
44         char sock_file[CTSVC_PATH_MAX_LEN] = {0};
45         snprintf(sock_file, sizeof(sock_file), CTSVC_SOCK_PATH"/%s", getuid(), CTSVC_SOCKET_FILE);
46
47         bzero(&caddr, sizeof(caddr));
48         caddr.sun_family = AF_UNIX;
49         snprintf(caddr.sun_path, sizeof(caddr.sun_path), "%s", sock_file);
50
51         __ctsvc_sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
52         RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC,
53                         "socket() Fail(errno = %d)", errno);
54
55         ret = connect(__ctsvc_sockfd, (struct sockaddr *)&caddr, sizeof(caddr));
56         if (-1 == ret) {
57                 CTS_ERR("connect() Fail(errno = %d)", errno);
58                 close(__ctsvc_sockfd);
59                 __ctsvc_sockfd = -1;
60                 return CONTACTS_ERROR_IPC;
61         }
62
63         __ctsvc_conn_refcnt++;
64         return CONTACTS_ERROR_NONE;
65 }
66
67 void ctsvc_socket_final(void)
68 {
69         if (1 < __ctsvc_conn_refcnt) {
70                 CTS_DBG("socket ref count : %d", __ctsvc_conn_refcnt);
71                 __ctsvc_conn_refcnt--;
72                 return;
73         }
74         else if (__ctsvc_conn_refcnt < 1) {
75                 CTS_DBG("Please call connection API. socket ref count : %d", __ctsvc_conn_refcnt);
76                 return;
77         }
78         __ctsvc_conn_refcnt--;
79
80         close(__ctsvc_sockfd);
81         __ctsvc_sockfd = -1;
82 }
83
84 static inline int __ctsvc_safe_write(int fd, const char *buf, int buf_size)
85 {
86         int ret, writed=0;
87         while (buf_size) {
88                 ret = write(fd, buf+writed, buf_size);
89                 if (-1 == ret) {
90                         if (EINTR == errno)
91                                 continue;
92                         else
93                                 return ret;
94                 }
95                 writed += ret;
96                 buf_size -= ret;
97         }
98         return writed;
99 }
100
101 static inline int __ctsvc_safe_read(int fd, char *buf, int buf_size)
102 {
103         int ret, read_size=0;
104         while (buf_size) {
105                 ret = read(fd, buf+read_size, buf_size);
106                 if (-1 == ret) {
107                         if (EINTR == errno)
108                                 continue;
109                         else
110                                 return ret;
111                 }
112                 read_size += ret;
113                 buf_size -= ret;
114         }
115         return read_size;
116 }
117
118 #ifdef ENABLE_SIM_FEATURE
119 static int __ctsvc_socket_handle_return(int fd, ctsvc_socket_msg_s *msg)
120 {
121         CTS_FN_CALL;
122         int ret;
123
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);
126
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]);
133
134         RETVM_IF(CTSVC_SOCKET_MSG_REQUEST_MAX_ATTACH < msg->attach_num, CONTACTS_ERROR_IPC,
135                         "Invalid msg(attach_num = %d)", msg->attach_num);
136
137         return CONTACTS_ERROR_NONE;
138 }
139
140 static void __ctsvc_remove_invalid_msg(int fd, int size)
141 {
142         int ret;
143         char dummy[CTSVC_SOCKET_MSG_SIZE] = {0};
144
145         while (size) {
146                 if (sizeof(dummy) < size) {
147                         ret = read(fd, dummy, sizeof(dummy));
148                         if (-1 == ret) {
149                                 if (EINTR == errno)
150                                         continue;
151                                 else
152                                         return;
153                         }
154                         size -= ret;
155                 }
156                 else {
157                         ret = read(fd, dummy, size);
158                         if (-1 == ret) {
159                                 if (EINTR == errno)
160                                         continue;
161                                 else
162                                         return;
163                         }
164                         size -= ret;
165                 }
166         }
167 }
168
169 int ctsvc_request_sim_import(int sim_slot_no)
170 {
171         int i, ret;
172         ctsvc_socket_msg_s msg = {0};
173         char src[64] = {0};
174
175         RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC, "socket is not connected");
176
177         msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_IMPORT_SIM;
178
179         snprintf(src, sizeof(src), "%d", sim_slot_no);
180         msg.attach_num = 1;
181         msg.attach_sizes[0] = strlen(src);
182
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);
185
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);
188
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);
192
193         for (i=0;i<msg.attach_num;i++)
194                 __ctsvc_remove_invalid_msg(__ctsvc_sockfd, msg.attach_sizes[i]);
195
196         return msg.val;
197 }
198
199 int ctsvc_request_sim_get_initialization_status(int sim_slot_no, bool *completed)
200 {
201         int ret = 0;
202         ctsvc_socket_msg_s msg = {0};
203         char dest[CTSVC_SOCKET_MSG_SIZE] = {0};
204         char src[64] = {0};
205
206         RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC, "socket is not connected");
207
208         msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_SIM_INIT_COMPLETE;
209
210         snprintf(src, sizeof(src), "%d", sim_slot_no);
211         msg.attach_num = 1;
212         msg.attach_sizes[0] = strlen(src);
213
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);
216
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);
219
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);
223
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);
226
227         if (atoi(dest) ==0)
228                 *completed = false;
229         else
230                 *completed = true;
231
232         CTS_INFO("sim init complete : %d", *completed);
233
234         return msg.val;
235 }
236
237 #endif /* ENABLE_SIM_FEATURE */