revise cumbersome structure that is a opaque type
[platform/core/connectivity/nfc-manager-neard.git] / daemon / net_nfc_server_transceive.c
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (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
7  *
8  *     http://floralicense.org/license/
9  *
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.
15  */
16
17 #include "net_nfc_typedef_internal.h"
18 #include "net_nfc_debug_internal.h"
19 #include "net_nfc_util_internal.h"
20 #include "net_nfc_util_gdbus_internal.h"
21 #include "net_nfc_server_controller.h"
22 #include "net_nfc_gdbus.h"
23 #include "net_nfc_server_common.h"
24 #include "net_nfc_server_tag.h"
25 #include "net_nfc_server_context.h"
26 #include "net_nfc_server_transceive.h"
27
28
29 static NetNfcGDbusTransceive *transceive_skeleton = NULL;
30
31 static void transceive_thread_func(gpointer user_data);
32
33 static void transceive_data_thread_func(gpointer user_data);
34
35 static gboolean transceive_handle(NetNfcGDbusTransceive *transceive,
36                 GDBusMethodInvocation *invocation,
37                 guint handle,
38                 guint dev_type,
39                 GVariant *arg_data,
40                 GVariant *smack_privilege,
41                 gpointer user_data);
42
43 static gboolean transceive_data_handle(NetNfcGDbusTransceive *transceive,
44                 GDBusMethodInvocation *invocation,
45                 guint handle,
46                 guint dev_type,
47                 GVariant *arg_data,
48                 GVariant *smack_privilege,
49                 gpointer user_data);
50
51
52 typedef struct _TransceiveSendData TransceiveSendData;
53
54 struct _TransceiveSendData
55 {
56         NetNfcGDbusTransceive *transceive;
57         GDBusMethodInvocation *invocation;
58         guint transceive_handle;
59         net_nfc_transceive_info_s transceive_info;
60 };
61
62 static void transceive_data_thread_func(gpointer user_data)
63 {
64         TransceiveSendData *transceive_data = user_data;
65         net_nfc_target_handle_s *handle =
66                 (net_nfc_target_handle_s *)transceive_data->transceive_handle;
67         net_nfc_error_e result = NET_NFC_OK;
68         data_s *data = NULL;
69         GVariant *resp_data = NULL;
70
71         /* use assert because it was checked in handle function */
72         g_assert(transceive_data != NULL);
73         g_assert(transceive_data->transceive != NULL);
74         g_assert(transceive_data->invocation != NULL);
75
76         if (net_nfc_server_target_connected(handle) == true)
77         {
78                 NFC_DBG("call transceive");
79
80                 if (net_nfc_controller_transceive(handle,
81                                         &transceive_data->transceive_info,
82                                         &data,
83                                         &result) == true)
84                 {
85                         if (data != NULL)
86                                 NFC_DBG("Transceive data received [%d]", data->length);
87                 }
88         }
89         else
90         {
91                 result = NET_NFC_TARGET_IS_MOVED_AWAY;
92         }
93
94         NFC_DBG("transceive result : %d", result);
95
96         resp_data = net_nfc_util_gdbus_data_to_variant(data);
97
98         net_nfc_gdbus_transceive_complete_transceive_data(
99                         transceive_data->transceive,
100                         transceive_data->invocation,
101                         (gint)result,
102                         resp_data);
103
104         if (data)
105         {
106                 g_free(data->buffer);
107                 g_free(data);
108         }
109
110         net_nfc_util_free_data(&transceive_data->transceive_info.trans_data);
111
112         g_object_unref(transceive_data->invocation);
113         g_object_unref(transceive_data->transceive);
114
115         g_free(transceive_data);
116 }
117
118 static gboolean transceive_data_handle(NetNfcGDbusTransceive *transceive,
119                 GDBusMethodInvocation *invocation,
120                 guint handle,
121                 guint dev_type,
122                 GVariant *arg_data,
123                 GVariant *smack_privilege,
124                 gpointer user_data)
125 {
126         TransceiveSendData *data;
127         gboolean result;
128
129         NFC_INFO(">>> REQUEST from [%s]",
130                         g_dbus_method_invocation_get_sender(invocation));
131
132         /* check privilege and update client context */
133         if (net_nfc_server_gdbus_check_privilege(invocation,
134                                 smack_privilege,
135                                 "nfc-manager",
136                                 "rw") == false) {
137                 NFC_ERR("permission denied, and finished request");
138
139                 return FALSE;
140         }
141
142         data = g_new0(TransceiveSendData, 1);
143         if (data == NULL)
144         {
145                 NFC_ERR("Memory allocation failed");
146                 g_dbus_method_invocation_return_dbus_error(invocation,
147                                 "org.tizen.NetNfcService.AllocationError",
148                                 "Can not allocate memory");
149
150                 return FALSE;
151         }
152
153         data->transceive = g_object_ref(transceive);
154         data->invocation = g_object_ref(invocation);
155         data->transceive_handle = handle;
156         data->transceive_info.dev_type = dev_type;
157         net_nfc_util_gdbus_variant_to_data_s(arg_data,
158                         &data->transceive_info.trans_data);
159
160         result = net_nfc_server_controller_async_queue_push(
161                         transceive_data_thread_func, data);
162         if (result == FALSE)
163         {
164                 g_dbus_method_invocation_return_dbus_error(invocation,
165                                 "org.tizen.NetNfcService.Transceive.ThreadError",
166                                 "can not push to controller thread");
167
168                 net_nfc_util_free_data(&data->transceive_info.trans_data);
169
170                 g_object_unref(data->transceive);
171                 g_object_unref(data->invocation);
172
173                 g_free(data);
174         }
175
176         return result;
177 }
178
179 static void transceive_thread_func(gpointer user_data)
180 {
181         TransceiveSendData *transceive_data = user_data;
182         net_nfc_target_handle_s *handle =
183                 (net_nfc_target_handle_s *)transceive_data->transceive_handle;
184         net_nfc_error_e result = NET_NFC_OK;
185         data_s *data = NULL;
186
187         /* use assert because it was checked in handle function */
188         g_assert(transceive_data != NULL);
189         g_assert(transceive_data->transceive != NULL);
190         g_assert(transceive_data->invocation != NULL);
191
192         if (net_nfc_server_target_connected(handle) == true)
193         {
194                 NFC_DBG("call transceive");
195
196                 if (net_nfc_controller_transceive(handle,
197                                         &transceive_data->transceive_info,
198                                         &data,
199                                         &result) == true)
200                 {
201                         if (data != NULL)
202                         {
203                                 NFC_DBG("Transceive data received [%d]", data->length);
204
205                                 /* free resource because it doesn't need */
206                                 g_free(data->buffer);
207                                 g_free(data);
208                         }
209                 }
210         }
211         else
212         {
213                 NFC_ERR("target is not connected");
214
215                 result = NET_NFC_TARGET_IS_MOVED_AWAY;
216         }
217
218         NFC_DBG("transceive result : %d", result);
219
220         net_nfc_gdbus_transceive_complete_transceive(
221                         transceive_data->transceive,
222                         transceive_data->invocation,
223                         (gint)result);
224
225         net_nfc_util_free_data(&transceive_data->transceive_info.trans_data);
226
227         g_object_unref(transceive_data->invocation);
228         g_object_unref(transceive_data->transceive);
229
230         g_free(transceive_data);
231 }
232
233 static gboolean transceive_handle(NetNfcGDbusTransceive *transceive,
234                 GDBusMethodInvocation *invocation,
235                 guint handle,
236                 guint dev_type,
237                 GVariant *arg_data,
238                 GVariant *smack_privilege,
239                 gpointer user_data)
240 {
241         TransceiveSendData *data;
242         gboolean result;
243
244         NFC_INFO(">>> REQUEST from [%s]",
245                         g_dbus_method_invocation_get_sender(invocation));
246
247         /* check privilege and update client context */
248         if (net_nfc_server_gdbus_check_privilege(invocation,
249                                 smack_privilege,
250                                 "nfc-manager",
251                                 "rw") == false) {
252                 NFC_ERR("permission denied, and finished request");
253
254                 return FALSE;
255         }
256
257         data = g_new0(TransceiveSendData, 1);
258         if (data == NULL)
259         {
260                 NFC_ERR("Memory allocation failed");
261                 g_dbus_method_invocation_return_dbus_error(invocation,
262                                 "org.tizen.NetNfcService.AllocationError",
263                                 "Can not allocate memory");
264
265                 return FALSE;
266         }
267
268         data->transceive = g_object_ref(transceive);
269         data->invocation = g_object_ref(invocation);
270         data->transceive_handle = handle;
271         data->transceive_info.dev_type = dev_type;
272         net_nfc_util_gdbus_variant_to_data_s(arg_data,
273                         &data->transceive_info.trans_data);
274
275         result = net_nfc_server_controller_async_queue_push(
276                         transceive_thread_func, data);
277         if (result == FALSE)
278         {
279                 g_dbus_method_invocation_return_dbus_error(invocation,
280                                 "org.tizen.NetNfcService.Transceive.ThreadError",
281                                 "can not push to controller thread");
282
283                 net_nfc_util_free_data(&data->transceive_info.trans_data);
284
285                 g_object_unref(data->transceive);
286                 g_object_unref(data->invocation);
287
288                 g_free(data);
289         }
290
291         return result;
292 }
293
294
295 gboolean net_nfc_server_transceive_init(GDBusConnection *connection)
296 {
297         GError *error = NULL;
298         gboolean result;
299
300         if (transceive_skeleton)
301                 g_object_unref(transceive_skeleton);
302
303         transceive_skeleton = net_nfc_gdbus_transceive_skeleton_new();
304
305         g_signal_connect(transceive_skeleton,
306                         "handle-transceive-data",
307                         G_CALLBACK(transceive_data_handle),
308                         NULL);
309
310         g_signal_connect(transceive_skeleton,
311                         "handle-transceive",
312                         G_CALLBACK(transceive_handle),
313                         NULL);
314
315         result = g_dbus_interface_skeleton_export(
316                         G_DBUS_INTERFACE_SKELETON(transceive_skeleton),
317                         connection,
318                         "/org/tizen/NetNfcService/Transceive",
319                         &error);
320         if (result == FALSE)
321         {
322                 g_error_free(error);
323                 g_object_unref(transceive_skeleton);
324                 transceive_skeleton = NULL;
325         }
326
327         return result;
328 }
329
330 void net_nfc_server_transceive_deinit(void)
331 {
332         if (transceive_skeleton)
333         {
334                 g_object_unref(transceive_skeleton);
335                 transceive_skeleton = NULL;
336         }
337 }