revise cumbersome structure that is a opaque type
[platform/core/connectivity/nfc-manager-neard.git] / client / net_nfc_client_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 <string.h>
18
19 #include "net_nfc_typedef_internal.h"
20 #include "net_nfc_debug_internal.h"
21 #include "net_nfc_util_internal.h"
22 #include "net_nfc_util_gdbus_internal.h"
23 #include "net_nfc_gdbus.h"
24 #include "net_nfc_client.h"
25 #include "net_nfc_client_manager.h"
26 #include "net_nfc_client_tag_internal.h"
27 #include "net_nfc_client_transceive.h"
28
29 static NetNfcGDbusTransceive *transceive_proxy = NULL;
30
31 static GVariant *transceive_data_to_transceive_variant(
32                 net_nfc_target_type_e dev_type,
33                 data_s *data);
34
35 static void transceive_call(GObject *source_object,
36                 GAsyncResult *res,
37                 gpointer user_data);
38
39 static void transceive_data_call(GObject *source_object,
40                 GAsyncResult *res,
41                 gpointer user_data);
42
43 static GVariant *transceive_data_to_transceive_variant(
44                 net_nfc_target_type_e devType,
45                 data_s *data)
46 {
47         data_s transceive_info = { NULL, };
48         GVariant *variant;
49
50         if (data == NULL)
51         {
52                 NFC_ERR("data is empty");
53                 return NULL;
54         }
55
56         switch (devType)
57         {
58         case NET_NFC_MIFARE_MINI_PICC :
59         case NET_NFC_MIFARE_1K_PICC :
60         case NET_NFC_MIFARE_4K_PICC :
61         case NET_NFC_MIFARE_ULTRA_PICC :
62                 if (net_nfc_util_alloc_data(&transceive_info,
63                                         data->length + 2) == true)
64                 {
65                         memcpy(transceive_info.buffer,
66                                         data->buffer,
67                                         data->length);
68
69                         net_nfc_util_compute_CRC(CRC_A,
70                                         transceive_info.buffer,
71                                         transceive_info.length);
72                 }
73                 break;
74
75         case NET_NFC_JEWEL_PICC :
76                 if (data->length > 9)
77                 {
78                         NFC_ERR("data length is larger than 9");
79                         return NULL;
80                 }
81
82                 if (net_nfc_util_alloc_data(&transceive_info, 9) == true)
83                 {
84                         memcpy(transceive_info.buffer,
85                                         data->buffer,
86                                         data->length);
87
88                         net_nfc_util_compute_CRC(CRC_B,
89                                         transceive_info.buffer,
90                                         transceive_info.length);
91                 }
92                 break;
93
94         default :
95                 if(net_nfc_util_alloc_data(&transceive_info,
96                                         data->length) == true)
97                 {
98                         memcpy(transceive_info.buffer,
99                                         data->buffer,
100                                         data->length);
101                 }
102                 break;
103         }
104
105         variant = net_nfc_util_gdbus_data_to_variant(&transceive_info);
106
107         net_nfc_util_free_data(&transceive_info);
108
109         return variant;
110 }
111
112 static void transceive_data_call(GObject *source_object,
113                 GAsyncResult *res, gpointer user_data)
114 {
115         NetNfcCallback *func_data = (NetNfcCallback *)user_data;
116         net_nfc_error_e out_result;
117         GVariant *out_data = NULL;
118         GError *error = NULL;
119
120         g_assert(user_data != NULL);
121
122         if (net_nfc_gdbus_transceive_call_transceive_data_finish(
123                                 NET_NFC_GDBUS_TRANSCEIVE(source_object),
124                                 (gint *)&out_result,
125                                 &out_data,
126                                 res,
127                                 &error) == FALSE)
128         {
129                 NFC_ERR("Can not finish transceive: %s", error->message);
130                 g_error_free(error);
131
132                 out_result = NET_NFC_IPC_FAIL;
133         }
134
135         if (func_data->callback != NULL)
136         {
137                 data_s resp = { NULL, };
138
139                 net_nfc_util_gdbus_variant_to_data_s(out_data, &resp);
140
141                 ((nfc_transceive_data_callback)func_data->callback)(
142                         out_result,
143                         &resp,
144                         func_data->user_data);
145
146                 net_nfc_util_free_data(&resp);
147         }
148
149         g_free(func_data);
150 }
151
152 static void transceive_call(GObject *source_object,
153                 GAsyncResult *res, gpointer user_data)
154 {
155         NetNfcCallback *func_data = (NetNfcCallback *)user_data;
156         net_nfc_error_e out_result;
157         GError *error = NULL;
158
159         g_assert(user_data != NULL);
160
161         if (net_nfc_gdbus_transceive_call_transceive_finish(
162                                 NET_NFC_GDBUS_TRANSCEIVE(source_object),
163                                 (gint *)&out_result,
164                                 res,
165                                 &error) == FALSE)
166         {
167                 NFC_ERR("Can not finish transceive: %s", error->message);
168                 g_error_free(error);
169
170                 out_result = NET_NFC_IPC_FAIL;
171         }
172
173         if (func_data->callback != NULL)
174         {
175                 ((nfc_transceive_callback)func_data->callback)(
176                         out_result,
177                         func_data->user_data);
178         }
179
180         g_free(func_data);
181 }
182
183 API net_nfc_error_e net_nfc_client_transceive(net_nfc_target_handle_s *handle,
184                 data_s *rawdata, nfc_transceive_callback callback, void *user_data)
185 {
186         net_nfc_target_info_s *target_info;
187         NetNfcCallback *funcdata;
188         GVariant *arg_data;
189
190         if (transceive_proxy == NULL)
191         {
192                 NFC_ERR("Can not get TransceiveProxy");
193
194                 return NET_NFC_NOT_INITIALIZED;
195         }
196
197
198         if (handle == NULL || rawdata == NULL)
199                 return NET_NFC_NULL_PARAMETER;
200
201         /* prevent executing daemon when nfc is off */
202         if (net_nfc_client_manager_is_activated() == false) {
203                 return NET_NFC_INVALID_STATE;
204         }
205
206         target_info = net_nfc_client_tag_get_client_target_info();
207         if (target_info == NULL || target_info->handle == NULL)
208                 return NET_NFC_NOT_CONNECTED;
209
210         NFC_DBG("send request :: transceive = [%p]", handle);
211
212         arg_data = transceive_data_to_transceive_variant(target_info->devType,
213                         rawdata);
214         if (arg_data == NULL) {
215                 return NET_NFC_INVALID_PARAM;
216         }
217
218         funcdata = g_try_new0(NetNfcCallback, 1);
219         if (funcdata == NULL) {
220                 g_variant_unref(arg_data);
221
222                 return NET_NFC_ALLOC_FAIL;
223         }
224
225         funcdata->callback = (gpointer)callback;
226         funcdata->user_data = user_data;
227
228         net_nfc_gdbus_transceive_call_transceive(transceive_proxy,
229                         GPOINTER_TO_UINT(handle),
230                         target_info->devType,
231                         arg_data,
232                         net_nfc_client_gdbus_get_privilege(),
233                         NULL,
234                         transceive_call,
235                         funcdata);
236
237         return NET_NFC_OK;
238 }
239
240 API net_nfc_error_e net_nfc_client_transceive_data(net_nfc_target_handle_s *handle,
241                 data_s *rawdata, nfc_transceive_data_callback callback, void *user_data)
242 {
243         net_nfc_target_info_s *target_info;
244         NetNfcCallback *funcdata;
245         GVariant *arg_data;
246
247         if (transceive_proxy == NULL)
248         {
249                 NFC_ERR("Can not get TransceiveProxy");
250
251                 return NET_NFC_NOT_INITIALIZED;
252         }
253
254         if (handle == NULL || rawdata == NULL)
255                 return NET_NFC_NULL_PARAMETER;
256
257         /* prevent executing daemon when nfc is off */
258         if (net_nfc_client_manager_is_activated() == false) {
259                 return NET_NFC_INVALID_STATE;
260         }
261
262         target_info = net_nfc_client_tag_get_client_target_info();
263         if (target_info == NULL || target_info->handle == NULL)
264                 return NET_NFC_NOT_CONNECTED;
265
266         NFC_DBG("send request :: transceive = [%p]", handle);
267
268         arg_data = transceive_data_to_transceive_variant(target_info->devType,
269                         rawdata);
270         if (arg_data == NULL) {
271                 return NET_NFC_INVALID_PARAM;
272         }
273
274         funcdata = g_try_new0(NetNfcCallback, 1);
275         if (funcdata == NULL) {
276                 g_variant_unref(arg_data);
277
278                 return NET_NFC_ALLOC_FAIL;
279         }
280
281         funcdata->callback = (gpointer)callback;
282         funcdata->user_data = user_data;
283
284         net_nfc_gdbus_transceive_call_transceive_data(transceive_proxy,
285                         GPOINTER_TO_UINT(handle),
286                         target_info->devType,
287                         arg_data,
288                         net_nfc_client_gdbus_get_privilege(),
289                         NULL,
290                         transceive_data_call,
291                         funcdata);
292
293         return NET_NFC_OK;
294 }
295
296 API net_nfc_error_e net_nfc_client_transceive_sync(net_nfc_target_handle_s *handle,
297                 data_s *rawdata)
298 {
299         net_nfc_target_info_s *target_info;
300         net_nfc_error_e out_result = NET_NFC_OK;
301         GError *error = NULL;
302         GVariant *arg_data;
303
304         if (handle == NULL || rawdata == NULL)
305                 return NET_NFC_NULL_PARAMETER;
306
307         if (transceive_proxy == NULL)
308         {
309                 NFC_ERR("Can not get TransceiveProxy");
310
311                 return NET_NFC_NOT_INITIALIZED;
312         }
313
314         /* prevent executing daemon when nfc is off */
315         if (net_nfc_client_manager_is_activated() == false) {
316                 return NET_NFC_INVALID_STATE;
317         }
318
319         target_info = net_nfc_client_tag_get_client_target_info();
320         if (target_info == NULL || target_info->handle == NULL)
321                 return NET_NFC_NOT_CONNECTED;
322
323         NFC_DBG("send request :: transceive = [%p]", handle);
324
325         arg_data = transceive_data_to_transceive_variant(target_info->devType,
326                         rawdata);
327         if (arg_data == NULL)
328                 return NET_NFC_ALLOC_FAIL;
329
330         if (net_nfc_gdbus_transceive_call_transceive_sync(transceive_proxy,
331                                 GPOINTER_TO_UINT(handle),
332                                 target_info->devType,
333                                 arg_data,
334                                 net_nfc_client_gdbus_get_privilege(),
335                                 (gint *)&out_result,
336                                 NULL,
337                                 &error) == FALSE)
338         {
339                 NFC_ERR("Transceive (sync call) failed: %s",
340                                 error->message);
341                 g_error_free(error);
342
343                 out_result = NET_NFC_IPC_FAIL;
344         }
345
346         return out_result;
347 }
348
349 API net_nfc_error_e net_nfc_client_transceive_data_sync(
350                 net_nfc_target_handle_s *handle, data_s *rawdata, data_s **response)
351 {
352         net_nfc_target_info_s *target_info;
353         net_nfc_error_e out_result = NET_NFC_OK;
354         GVariant *out_data = NULL;
355         GError *error = NULL;
356         GVariant *arg_data;
357
358         if (handle == NULL || rawdata == NULL)
359                 return NET_NFC_NULL_PARAMETER;
360
361         if (transceive_proxy == NULL)
362         {
363                 NFC_ERR("Can not get TransceiveProxy");
364
365                 return NET_NFC_NOT_INITIALIZED;
366         }
367
368         /* prevent executing daemon when nfc is off */
369         if (net_nfc_client_manager_is_activated() == false) {
370                 return NET_NFC_INVALID_STATE;
371         }
372
373         target_info = net_nfc_client_tag_get_client_target_info();
374         if (target_info == NULL || target_info->handle == NULL)
375                 return NET_NFC_NOT_CONNECTED;
376
377         NFC_DBG("send request :: transceive = [%p]", handle);
378
379         arg_data = transceive_data_to_transceive_variant(target_info->devType,
380                         rawdata);
381         if (arg_data == NULL)
382                 return NET_NFC_ALLOC_FAIL;
383
384         if (net_nfc_gdbus_transceive_call_transceive_data_sync(
385                                 transceive_proxy,
386                                 GPOINTER_TO_UINT(handle),
387                                 target_info->devType,
388                                 arg_data,
389                                 net_nfc_client_gdbus_get_privilege(),
390                                 (gint *)&out_result,
391                                 &out_data,
392                                 NULL,
393                                 &error) == FALSE)
394         {
395                 NFC_ERR("Transceive (sync call) failed: %s",
396                                 error->message);
397                 g_error_free(error);
398
399                 out_result = NET_NFC_IPC_FAIL;
400         }
401
402         if (response && out_data != NULL)
403         {
404                 *response = net_nfc_util_gdbus_variant_to_data(out_data);
405         }
406
407         return out_result;
408 }
409
410
411 net_nfc_error_e net_nfc_client_transceive_init(void)
412 {
413         GError *error = NULL;
414
415         if (transceive_proxy)
416         {
417                 NFC_WARN("Already initialized");
418                 return NET_NFC_OK;
419         }
420
421         transceive_proxy = net_nfc_gdbus_transceive_proxy_new_for_bus_sync(
422                         G_BUS_TYPE_SYSTEM,
423                         G_DBUS_PROXY_FLAGS_NONE,
424                         "org.tizen.NetNfcService",
425                         "/org/tizen/NetNfcService/Transceive",
426                         NULL,
427                         &error);
428         if (transceive_proxy == NULL)
429         {
430                 NFC_ERR("Can not create proxy : %s", error->message);
431                 g_error_free(error);
432
433                 return NET_NFC_UNKNOWN_ERROR;
434         }
435
436         return NET_NFC_OK;
437 }
438
439 void net_nfc_client_transceive_deinit(void)
440 {
441         if (transceive_proxy)
442         {
443                 g_object_unref(transceive_proxy);
444                 transceive_proxy = NULL;
445         }
446 }