2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
21 #include <sys/types.h>
23 #include <sys/epoll.h>
32 #include <glib-object.h>
36 #include "net_nfc_typedef_internal.h"
37 #include "net_nfc_debug_internal.h"
38 #include "net_nfc_util_defines.h"
39 #include "net_nfc_util_internal.h"
40 #include "net_nfc_util_hce.h"
41 #include "net_nfc_client_hce.h"
42 #include "net_nfc_client_hce_ipc.h"
45 static pthread_mutex_t g_client_ipc_mutex = PTHREAD_MUTEX_INITIALIZER;
46 static pthread_mutex_t cb_lock = PTHREAD_MUTEX_INITIALIZER;
48 static int hce_client_socket = -1;
49 static GIOChannel *hce_client_channel = NULL;
50 static guint hce_client_src_id = 0;
53 static void __set_non_block_socket(int socket)
57 flags = fcntl(socket, F_GETFL);
60 if (fcntl(socket, F_SETFL, flags) < 0)
61 DEBUG_ERR_MSG("fcntl, executing nonblock error");
64 static bool __receive_data_from_server(int socket, data_s *data)
70 /* first, receive length */
71 ret = recv(socket, (void *)&len, sizeof(len), 0);
72 if (ret != sizeof(len)) {
73 DEBUG_ERR_MSG("recv failed, socket [%d], result [%d]", socket, ret);
79 DEBUG_ERR_MSG("too large message, socket [%d], len [%d]", socket, len);
84 result = net_nfc_util_init_data(data, len);
88 /* second, receive buffer */
90 ret = recv(socket, data->buffer + offset, data->length - offset, 0);
95 } while (offset < len);
98 DEBUG_ERR_MSG("recv failed, socket [%d], offset [%d], len [%d]", socket, offset, len);
100 net_nfc_util_clear_data(data);
104 DEBUG_CLIENT_MSG("recv success, length [%d]", offset);
107 DEBUG_ERR_MSG("net_nfc_util_init_data failed");
113 static bool __process_server_message()
118 if (__receive_data_from_server(hce_client_socket, &data) == true) {
119 net_nfc_hce_data_t *header;
122 header = (net_nfc_hce_data_t *)data.buffer;
124 temp.buffer = header->data;
125 temp.length = data.length - sizeof(net_nfc_hce_data_t);
127 net_nfc_client_hce_process_received_event(header->type,
128 (net_nfc_target_handle_h)GUINT_TO_POINTER(header->handle), (data_h)&temp);
132 DEBUG_ERR_MSG("__receive_data_from_client failed");
140 static bool __send_data_to_server(int socket, data_s *data)
144 ret = send(socket, data->buffer, data->length, MSG_NOSIGNAL);
146 DEBUG_ERR_MSG("send failed, socket [%d]", socket);
154 bool net_nfc_server_hce_ipc_send_to_server(int type,
155 net_nfc_target_handle_s *handle, data_s *data)
159 uint32_t len = sizeof(net_nfc_hce_data_t);
161 if (data != NULL && data->length > 0)
164 ret = net_nfc_util_init_data(&temp, len + sizeof(len));
166 net_nfc_hce_data_t *header;
168 *(uint32_t *)(temp.buffer) = len;
169 header = (net_nfc_hce_data_t *)(temp.buffer + sizeof(len));
172 header->handle = GPOINTER_TO_UINT(handle);
174 if (data != NULL && data->length > 0)
175 memcpy(header->data, data->buffer, data->length);
177 ret = __send_data_to_server(hce_client_socket, &temp);
179 net_nfc_util_clear_data(&temp);
181 DEBUG_ERR_MSG("net_nfc_util_init_data failed");
187 /******************************************************************************/
189 static inline void net_nfc_client_ipc_lock()
191 pthread_mutex_lock(&g_client_ipc_mutex);
194 static inline void net_nfc_client_ipc_unlock()
196 pthread_mutex_unlock(&g_client_ipc_mutex);
199 bool net_nfc_client_hce_ipc_is_initialized()
201 return (hce_client_socket != -1 && hce_client_channel != NULL);
204 static net_nfc_error_e _finalize_client_socket()
206 net_nfc_error_e result = NET_NFC_OK;
208 net_nfc_client_ipc_lock();
210 if (hce_client_src_id > 0) {
211 g_source_remove(hce_client_src_id);
212 hce_client_src_id = 0;
215 if (hce_client_channel != NULL) {
216 g_io_channel_unref(hce_client_channel);
217 hce_client_channel = NULL;
220 if (hce_client_socket != -1) {
221 shutdown(hce_client_socket, SHUT_WR);
222 close(hce_client_socket);
223 hce_client_socket = -1;
225 INFO_MSG("client socket closed");
228 net_nfc_client_ipc_unlock();
233 static gboolean __on_io_event_cb(GIOChannel *channel, GIOCondition condition,
236 if ((G_IO_ERR & condition) || (G_IO_HUP & condition)) {
237 DEBUG_CLIENT_MSG("client socket is closed");
239 /* clean up client context */
240 net_nfc_client_hce_ipc_deinit();
243 } else if (G_IO_NVAL & condition) {
244 DEBUG_CLIENT_MSG("INVALID socket");
247 } else if (G_IO_IN & condition) {
248 if (channel != hce_client_channel) {
249 DEBUG_CLIENT_MSG("unknown channel");
254 DEBUG_CLIENT_MSG("message from server to client socket");
256 if (__process_server_message() == false) {
257 DEBUG_ERR_MSG("__process_server_message failed");
259 net_nfc_client_hce_ipc_deinit();
264 DEBUG_CLIENT_MSG("IO ERROR. socket is closed ");
266 /* clean up client context */
267 net_nfc_client_hce_ipc_deinit();
275 net_nfc_error_e net_nfc_client_hce_ipc_init()
277 net_nfc_error_e result = NET_NFC_OK;
278 struct sockaddr_un saddrun_rv;
279 socklen_t len_saddr = 0;
280 pthread_mutexattr_t attr;
282 if (net_nfc_client_hce_ipc_is_initialized() == true) {
283 DEBUG_CLIENT_MSG("client is already initialized");
285 return NET_NFC_ALREADY_INITIALIZED;
288 pthread_mutexattr_init(&attr);
289 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
290 pthread_mutex_init(&cb_lock, &attr);
292 memset(&saddrun_rv, 0, sizeof(struct sockaddr_un));
294 net_nfc_client_ipc_lock();
296 hce_client_socket = socket(AF_UNIX, SOCK_STREAM, 0);
297 if (hce_client_socket == -1) {
298 DEBUG_ERR_MSG("get socket is failed");
300 result = NET_NFC_IPC_FAIL;
304 __set_non_block_socket(hce_client_socket);
306 saddrun_rv.sun_family = AF_UNIX;
307 strncpy(saddrun_rv.sun_path, NET_NFC_HCE_SERVER_DOMAIN, sizeof(saddrun_rv.sun_path) - 1);
309 len_saddr = sizeof(saddrun_rv.sun_family) + strlen(NET_NFC_HCE_SERVER_DOMAIN);
311 if (connect(hce_client_socket, (struct sockaddr *)&saddrun_rv, len_saddr) < 0) {
312 DEBUG_ERR_MSG("error is occured");
313 result = NET_NFC_IPC_FAIL;
318 GIOCondition condition = (GIOCondition)(G_IO_ERR | G_IO_HUP | G_IO_IN);
320 hce_client_channel = g_io_channel_unix_new(hce_client_socket);
321 if (hce_client_channel == NULL) {
322 DEBUG_ERR_MSG(" g_io_channel_unix_new is failed ");
323 result = NET_NFC_IPC_FAIL;
328 hce_client_src_id = g_io_add_watch(hce_client_channel, condition,
329 __on_io_event_cb, NULL);
330 if (hce_client_src_id < 1) {
331 DEBUG_ERR_MSG(" g_io_add_watch is failed ");
332 result = NET_NFC_IPC_FAIL;
337 DEBUG_CLIENT_MSG("client socket is ready");
339 net_nfc_client_ipc_unlock();
344 DEBUG_ERR_MSG("error while initializing client ipc");
346 net_nfc_client_ipc_unlock();
348 _finalize_client_socket();
353 void net_nfc_client_hce_ipc_deinit()
355 if (net_nfc_client_hce_ipc_is_initialized() == true)
356 _finalize_client_socket();