Sync code with Tizen 3.0 branch
[platform/core/api/nfc.git] / src / net_nfc_client_handover.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_ndef_message.h"
21 #include "net_nfc_util_gdbus_internal.h"
22 #include "net_nfc_gdbus.h"
23 #include "net_nfc_data.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_handover.h"
28
29 /* LCOV_EXCL_START */
30
31 #ifndef NET_NFC_EXPORT_API
32 #define NET_NFC_EXPORT_API __attribute__((visibility("default")))
33 #endif
34
35 typedef struct _handover_handler_t {
36         net_nfc_connection_handover_event_cb handover_event_cb;
37         gpointer handover_event_data;
38 }
39 handover_handler_t;
40
41 static NetNfcGDbusHandover *handover_proxy = NULL;
42 static handover_handler_t handover_callbacks;
43
44 static void p2p_connection_handover(GObject *source_object,
45                                 GAsyncResult *res,
46                                 gpointer user_data);
47
48 static void __started(NetNfcGDbusHandover *object,
49         GVariant *arg_message)
50 {
51         data_s message;
52
53         INFO_MSG(">>> SIGNAL arrived");
54
55         net_nfc_util_gdbus_variant_to_data_s(arg_message, &message);
56
57         if (handover_callbacks.handover_event_cb != NULL) {
58                 handover_callbacks.handover_event_cb(NET_NFC_HANDOVER_START,
59                         NET_NFC_OK, NET_NFC_CONN_HANDOVER_CARRIER_UNKNOWN,
60                         NULL, &message,
61                         handover_callbacks.handover_event_data);
62         }
63
64         net_nfc_util_clear_data(&message);
65 }
66
67 static void __finished(NetNfcGDbusHandover *object,
68         gint arg_result,
69         gint arg_type,
70         GVariant *arg_address,
71         GVariant *arg_message)
72 {
73         data_s address, message;
74
75         INFO_MSG(">>> SIGNAL arrived");
76
77         net_nfc_util_gdbus_variant_to_data_s(arg_address, &address);
78         net_nfc_util_gdbus_variant_to_data_s(arg_message, &message);
79
80         if (handover_callbacks.handover_event_cb != NULL) {
81                 handover_callbacks.handover_event_cb(NET_NFC_HANDOVER_FINISH,
82                         arg_result, arg_type, &address, &message,
83                         handover_callbacks.handover_event_data);
84         }
85
86         net_nfc_util_clear_data(&message);
87         net_nfc_util_clear_data(&address);
88 }
89
90 static void p2p_connection_handover(GObject *source_object,
91                                 GAsyncResult *res,
92                                 gpointer user_data)
93 {
94         NetNfcCallback *func_data = (NetNfcCallback *)user_data;
95         net_nfc_error_e result;
96         GVariant *data = NULL;
97         net_nfc_conn_handover_carrier_type_e type =
98                 NET_NFC_CONN_HANDOVER_CARRIER_UNKNOWN;
99         GError *error = NULL;
100         data_s arg_data;
101
102         g_assert(user_data != NULL);
103
104         if (handover_proxy == NULL) {
105                 if (net_nfc_client_handover_init() != NET_NFC_OK) {
106                         DEBUG_ERR_MSG("handover_proxy fail");
107                         /* FIXME : return result of this error */
108                         return;
109                 }
110         }
111
112         if (net_nfc_gdbus_handover_call_request_finish(handover_proxy,
113                                                 (gint *)&result,
114                                                 (gint *)&type,
115                                                 &data,
116                                                 res,
117                                                 &error) == FALSE) {
118                 DEBUG_ERR_MSG("Can not finish"
119                          " connection handover: %s", error->message);
120                 result = NET_NFC_IPC_FAIL;
121
122                 g_error_free(error);
123         }
124
125         if (func_data->callback != NULL) {
126                 net_nfc_p2p_connection_handover_completed_cb callback =
127                         (net_nfc_p2p_connection_handover_completed_cb)func_data->callback;
128
129                 net_nfc_util_gdbus_variant_to_data_s(data, &arg_data);
130
131                 callback(result,
132                         type,
133                         &arg_data,
134                         func_data->user_data);
135
136                 net_nfc_util_clear_data(&arg_data);
137         }
138
139         g_free(func_data);
140 }
141
142
143 NET_NFC_EXPORT_API
144 net_nfc_error_e net_nfc_client_handover_free_alternative_carrier_data(
145                         net_nfc_connection_handover_info_h info_handle)
146 {
147         net_nfc_connection_handover_info_s *info =
148                 (net_nfc_connection_handover_info_s *)info_handle;
149
150         if (info_handle == NULL)
151                 return NET_NFC_NULL_PARAMETER;
152
153         if (info->data.buffer != NULL)
154                 _net_nfc_util_free_mem(info->data.buffer);
155
156         _net_nfc_util_free_mem(info);
157
158         return NET_NFC_OK;
159 }
160
161
162 NET_NFC_EXPORT_API
163 net_nfc_error_e net_nfc_client_handover_get_alternative_carrier_type(
164                         net_nfc_connection_handover_info_h info_handle,
165                         net_nfc_conn_handover_carrier_type_e *type)
166 {
167         net_nfc_connection_handover_info_s *info =
168                 (net_nfc_connection_handover_info_s *)info_handle;
169
170         if (info_handle == NULL || type == NULL)
171                 return NET_NFC_NULL_PARAMETER;
172
173         *type = info->type;
174
175         return NET_NFC_OK;
176 }
177
178 NET_NFC_EXPORT_API
179 net_nfc_error_e net_nfc_client_handover_get_alternative_carrier_data(
180                         net_nfc_connection_handover_info_h info_handle,
181                         data_h *data)
182 {
183         net_nfc_connection_handover_info_s *info =
184                 (net_nfc_connection_handover_info_s *)info_handle;
185
186         if (info_handle == NULL || data == NULL)
187                 return NET_NFC_NULL_PARAMETER;
188
189         return net_nfc_create_data(data, info->data.buffer, info->data.length);
190 }
191
192
193 NET_NFC_EXPORT_API
194 net_nfc_error_e net_nfc_client_p2p_connection_handover(
195                         net_nfc_target_handle_h handle,
196                         net_nfc_conn_handover_carrier_type_e arg_type,
197                         net_nfc_p2p_connection_handover_completed_cb callback,
198                         void *cb_data)
199 {
200
201         net_nfc_target_handle_s *tag_handle = (net_nfc_target_handle_s *)handle;
202         NetNfcCallback *funcdata;
203
204         if (handover_proxy == NULL) {
205                 if (net_nfc_client_handover_init() != NET_NFC_OK) {
206                         DEBUG_ERR_MSG("handover_proxy fail");
207                         return NET_NFC_NOT_INITIALIZED;
208                 }
209         }
210
211         /* prevent executing daemon when nfc is off */
212         if (net_nfc_client_manager_is_activated() == false)
213                 return NET_NFC_NOT_ACTIVATED;
214
215         funcdata = g_try_new0(NetNfcCallback, 1);
216         if (funcdata == NULL)
217                 return NET_NFC_ALLOC_FAIL;
218
219         funcdata->callback = (gpointer)callback;
220         funcdata->user_data = cb_data;
221
222         net_nfc_gdbus_handover_call_request(handover_proxy,
223                                         GPOINTER_TO_UINT(tag_handle),
224                                         arg_type,
225                                         NULL,
226                                         p2p_connection_handover,
227                                         funcdata);
228
229         return NET_NFC_OK;
230 }
231
232
233 NET_NFC_EXPORT_API
234 net_nfc_error_e net_nfc_client_p2p_connection_handover_sync(
235         net_nfc_target_handle_h handle,
236         net_nfc_conn_handover_carrier_type_e arg_type,
237         net_nfc_conn_handover_carrier_type_e *out_carrier,
238         data_h *out_ac_data)
239 {
240         net_nfc_target_handle_s *tag_handle = (net_nfc_target_handle_s *)handle;
241         GVariant *out_data = NULL;
242         net_nfc_error_e out_result = NET_NFC_OK;
243         net_nfc_conn_handover_carrier_type_e out_type =
244                 NET_NFC_CONN_HANDOVER_CARRIER_UNKNOWN;
245         GError *error = NULL;
246
247         if (handover_proxy == NULL) {
248                 if (net_nfc_client_handover_init() != NET_NFC_OK) {
249                         DEBUG_ERR_MSG("handover_proxy fail");
250                         return NET_NFC_NOT_INITIALIZED;
251                 }
252         }
253
254         /* prevent executing daemon when nfc is off */
255         if (net_nfc_client_manager_is_activated() == false)
256                 return NET_NFC_NOT_ACTIVATED;
257
258         if (net_nfc_gdbus_handover_call_request_sync(handover_proxy,
259                 GPOINTER_TO_UINT(tag_handle),
260                 arg_type,
261                 (gint32 *)&out_result,
262                 (gint32 *)&out_type,
263                 &out_data,
264                 NULL,
265                 &error) == TRUE) {
266                 if (out_carrier)
267                         *out_carrier = out_type;
268
269                 if (out_ac_data)
270                         *out_ac_data = net_nfc_util_gdbus_variant_to_data(out_data);
271         } else {
272                 DEBUG_ERR_MSG("handover (sync call) failed: %s", error->message);
273                 out_result = NET_NFC_IPC_FAIL;
274
275                 g_error_free(error);
276         }
277
278         return out_result;
279 }
280
281 NET_NFC_EXPORT_API
282 void net_nfc_client_handover_set_handover_event_cb(
283         net_nfc_connection_handover_event_cb callback,
284         void *user_data)
285 {
286         if (callback == NULL)
287                 return;
288
289         if (handover_proxy == NULL) {
290                 if (net_nfc_client_handover_init() != NET_NFC_OK) {
291                         DEBUG_ERR_MSG("handover_proxy fail");
292                         return;
293                 }
294         }
295
296         handover_callbacks.handover_event_cb = callback;
297         handover_callbacks.handover_event_data = user_data;
298 }
299
300
301 NET_NFC_EXPORT_API
302 void net_nfc_client_handover_unset_handover_event_cb(void)
303 {
304         handover_callbacks.handover_event_cb = NULL;
305         handover_callbacks.handover_event_data = NULL;
306 }
307
308
309 net_nfc_error_e net_nfc_client_handover_init(void)
310 {
311         GError *error = NULL;
312
313         if (handover_proxy) {
314                 DEBUG_CLIENT_MSG("Already initialized");
315
316                 return NET_NFC_OK;
317         }
318
319         handover_proxy = net_nfc_gdbus_handover_proxy_new_for_bus_sync(
320                                         G_BUS_TYPE_SYSTEM,
321                                         G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
322                                         "org.tizen.NetNfcService",
323                                         "/org/tizen/NetNfcService/Handover",
324                                         NULL,
325                                         &error);
326         if (handover_proxy == NULL) {
327                 DEBUG_ERR_MSG("Can not create proxy : %s", error->message);
328                 g_error_free(error);
329
330                 return NET_NFC_UNKNOWN_ERROR;
331         }
332
333         g_signal_connect(handover_proxy, "started",
334                 G_CALLBACK(__started), NULL);
335
336         g_signal_connect(handover_proxy, "finished",
337                 G_CALLBACK(__finished), NULL);
338
339         return NET_NFC_OK;
340 }
341
342
343 void net_nfc_client_handover_deinit(void)
344 {
345         if (handover_proxy) {
346                 g_object_unref(handover_proxy);
347                 handover_proxy = NULL;
348         }
349 }
350
351 /* LCOV_EXCL_STOP */
352