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