Fix .service and install it into dbus system service directory
[platform/core/connectivity/nfc-manager-neard.git] / daemon / net_nfc_server_ndef.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
24 #include "net_nfc_server_common.h"
25 #include "net_nfc_server_context.h"
26 #include "net_nfc_server_tag.h"
27 #include "net_nfc_server_ndef.h"
28
29 typedef struct _ReadData ReadData;
30
31 struct _ReadData
32 {
33         NetNfcGDbusNdef *ndef;
34         GDBusMethodInvocation *invocation;
35         guint32 handle;
36 };
37
38 typedef struct _WriteData WriteData;
39
40 struct _WriteData
41 {
42         NetNfcGDbusNdef *ndef;
43         GDBusMethodInvocation *invocation;
44         guint32 handle;
45         data_s data;
46 };
47
48 typedef struct _MakeReadOnlyData MakeReadOnlyData;
49
50 struct _MakeReadOnlyData
51 {
52         NetNfcGDbusNdef *ndef;
53         GDBusMethodInvocation *invocation;
54         guint32 handle;
55 };
56
57 typedef struct _FormatData FormatData;
58
59 struct _FormatData
60 {
61         NetNfcGDbusNdef *ndef;
62         GDBusMethodInvocation *invocation;
63         guint32 handle;
64         data_s key;
65 };
66
67
68 static NetNfcGDbusNdef *ndef_skeleton = NULL;
69
70 static void ndef_read_thread_func(gpointer user_data);
71
72 static void ndef_write_thread_func(gpointer user_data);
73
74 static void ndef_make_read_only_thread_func(gpointer user_data);
75
76 static void ndef_format_thread_func(gpointer user_data);
77
78 /* methods */
79 static gboolean ndef_handle_read(NetNfcGDbusNdef *ndef,
80                 GDBusMethodInvocation *invocation,
81                 guint32 arg_handle,
82                 GVariant *smack_privilege,
83                 gpointer user_data);
84
85 static gboolean ndef_handle_write(NetNfcGDbusNdef *ndef,
86                 GDBusMethodInvocation *invocation,
87                 guint32 arg_handle,
88                 GVariant *arg_data,
89                 GVariant *smack_privilege,
90                 gpointer user_data);
91
92 static gboolean ndef_handle_make_read_only(NetNfcGDbusNdef *ndef,
93                 GDBusMethodInvocation *invocation,
94                 guint32 arg_handle,
95                 GVariant *smack_privilege,
96                 gpointer user_data);
97
98 static gboolean ndef_handle_format(NetNfcGDbusNdef *ndef,
99                 GDBusMethodInvocation *invocation,
100                 guint32 arg_handle,
101                 GVariant *arg_key,
102                 GVariant *smack_privilege,
103                 gpointer user_data);
104
105
106 static void ndef_read_thread_func(gpointer user_data)
107 {
108         ReadData *data = user_data;
109
110         net_nfc_target_handle_s *handle;
111         net_nfc_error_e result;
112         data_s *read_data = NULL;
113         GVariant *data_variant;
114
115         g_assert(data != NULL);
116         g_assert(data->ndef != NULL);
117         g_assert(data->invocation != NULL);
118
119         handle = GUINT_TO_POINTER(data->handle);
120
121         if (net_nfc_server_target_connected(handle) == true) {
122                 net_nfc_controller_read_ndef(handle, &read_data, &result);
123         } else {
124                 result = NET_NFC_TARGET_IS_MOVED_AWAY;
125         }
126
127         data_variant = net_nfc_util_gdbus_data_to_variant(read_data);
128
129         net_nfc_gdbus_ndef_complete_read(data->ndef,
130                         data->invocation,
131                         (gint)result,
132                         data_variant);
133
134         if (read_data) {
135                 net_nfc_util_free_data(read_data);
136                 g_free(read_data);
137         }
138
139         g_object_unref(data->invocation);
140         g_object_unref(data->ndef);
141
142         g_free(data);
143 }
144
145 static void ndef_write_thread_func(gpointer user_data)
146 {
147         WriteData *data = user_data;
148
149         net_nfc_target_handle_s *handle;
150         net_nfc_error_e result;
151
152         g_assert(data != NULL);
153         g_assert(data->ndef != NULL);
154         g_assert(data->invocation != NULL);
155
156         handle = GUINT_TO_POINTER(data->handle);
157
158         if (net_nfc_server_target_connected(handle) == true) {
159                 net_nfc_controller_write_ndef(handle, &data->data, &result);
160         } else {
161                 result = NET_NFC_TARGET_IS_MOVED_AWAY;
162         }
163
164         net_nfc_gdbus_ndef_complete_write(data->ndef,
165                         data->invocation,
166                         (gint)result);
167
168         net_nfc_util_free_data(&data->data);
169
170         g_object_unref(data->invocation);
171         g_object_unref(data->ndef);
172
173         g_free(data);
174 }
175
176 static void ndef_make_read_only_thread_func(gpointer user_data)
177 {
178         MakeReadOnlyData *data = user_data;
179
180         net_nfc_target_handle_s *handle;
181         net_nfc_error_e result;
182
183         g_assert(data != NULL);
184         g_assert(data->ndef != NULL);
185         g_assert(data->invocation != NULL);
186
187         handle = GUINT_TO_POINTER(data->handle);
188
189         if (net_nfc_server_target_connected(handle) == true) {
190                 net_nfc_controller_make_read_only_ndef(handle, &result);
191         } else {
192                 result = NET_NFC_TARGET_IS_MOVED_AWAY;
193         }
194
195         net_nfc_gdbus_ndef_complete_make_read_only(data->ndef,
196                         data->invocation,
197                         (gint)result);
198
199         g_object_unref(data->invocation);
200         g_object_unref(data->ndef);
201
202         g_free(data);
203 }
204
205 static void ndef_format_thread_func(gpointer user_data)
206 {
207         FormatData *data = user_data;
208
209         net_nfc_target_handle_s *handle;
210         net_nfc_error_e result;
211
212         g_assert(data != NULL);
213         g_assert(data->ndef != NULL);
214         g_assert(data->invocation != NULL);
215
216         handle = GUINT_TO_POINTER(data->handle);
217
218         if (net_nfc_server_target_connected(handle) == true) {
219                 net_nfc_controller_format_ndef(handle, &data->key, &result);
220         } else {
221                 result = NET_NFC_TARGET_IS_MOVED_AWAY;
222         }
223
224         net_nfc_gdbus_ndef_complete_format(data->ndef,
225                         data->invocation,
226                         (gint)result);
227
228         net_nfc_util_free_data(&data->key);
229
230         g_object_unref(data->invocation);
231         g_object_unref(data->ndef);
232
233         g_free(data);
234 }
235
236 static gboolean ndef_handle_read(NetNfcGDbusNdef *ndef,
237                 GDBusMethodInvocation *invocation,
238                 guint32 arg_handle,
239                 GVariant *smack_privilege,
240                 gpointer user_data)
241 {
242         ReadData *data;
243         gboolean result;
244
245         NFC_INFO(">>> REQUEST from [%s]",
246                         g_dbus_method_invocation_get_sender(invocation));
247
248         /* check privilege and update client context */
249         if (net_nfc_server_gdbus_check_privilege(invocation,
250                                 smack_privilege,
251                                 "nfc-manager::tag",
252                                 "r") == false) {
253                 NFC_ERR("permission denied, and finished request");
254
255                 return FALSE;
256         }
257
258         data = g_new0(ReadData, 1);
259         if (data == NULL)
260         {
261                 NFC_ERR("Memory allocation failed");
262                 g_dbus_method_invocation_return_dbus_error(invocation,
263                                 "org.tizen.NetNfcService.AllocationError",
264                                 "Can not allocate memory");
265
266                 return FALSE;
267         }
268
269         data->ndef = g_object_ref(ndef);
270         data->invocation = g_object_ref(invocation);
271         data->handle = arg_handle;
272
273         result = net_nfc_server_controller_async_queue_push(
274                         ndef_read_thread_func,
275                         data);
276         if (result == FALSE)
277         {
278                 g_dbus_method_invocation_return_dbus_error(invocation,
279                                 "org.tizen.NetNfcService.Ndef.ThreadError",
280                                 "can not push to controller thread");
281
282                 g_object_unref(data->invocation);
283                 g_object_unref(data->ndef);
284
285                 g_free(data);
286         }
287
288         return result;
289 }
290
291 static gboolean ndef_handle_write(NetNfcGDbusNdef *ndef,
292                 GDBusMethodInvocation *invocation,
293                 guint32 arg_handle,
294                 GVariant *arg_data,
295                 GVariant *smack_privilege,
296                 gpointer user_data)
297 {
298         WriteData *data;
299         gboolean result;
300
301         NFC_INFO(">>> REQUEST from [%s]",
302                         g_dbus_method_invocation_get_sender(invocation));
303
304         /* check privilege and update client context */
305         if (net_nfc_server_gdbus_check_privilege(invocation,
306                                 smack_privilege,
307                                 "nfc-manager::tag",
308                                 "w") == false) {
309                 NFC_ERR("permission denied, and finished request");
310
311                 return FALSE;
312         }
313
314         data = g_new0(WriteData, 1);
315         if (data == NULL)
316         {
317                 NFC_ERR("Memory allocation failed");
318                 g_dbus_method_invocation_return_dbus_error(invocation,
319                                 "org.tizen.NetNfcService.AllocationError",
320                                 "Can not allocate memory");
321
322                 return FALSE;
323         }
324
325         data->ndef = g_object_ref(ndef);
326         data->invocation = g_object_ref(invocation);
327         data->handle = arg_handle;
328
329         net_nfc_util_gdbus_variant_to_data_s(arg_data, &data->data);
330
331         result = net_nfc_server_controller_async_queue_push(
332                         ndef_write_thread_func,
333                         data);
334         if (result == FALSE)
335         {
336                 g_dbus_method_invocation_return_dbus_error(invocation,
337                                 "org.tizen.NetNfcService.Ndef.ThreadError",
338                                 "can not push to controller thread");
339
340                 net_nfc_util_free_data(&data->data);
341
342                 g_object_unref(data->invocation);
343                 g_object_unref(data->ndef);
344
345                 g_free(data);
346         }
347
348         return result;
349 }
350
351 static gboolean ndef_handle_make_read_only(NetNfcGDbusNdef *ndef,
352                 GDBusMethodInvocation *invocation,
353                 guint32 arg_handle,
354                 GVariant *smack_privilege,
355                 gpointer user_data)
356 {
357         MakeReadOnlyData *data;
358         gboolean result;
359
360         NFC_INFO(">>> REQUEST from [%s]",
361                         g_dbus_method_invocation_get_sender(invocation));
362
363         /* check privilege and update client context */
364         if (net_nfc_server_gdbus_check_privilege(invocation,
365                                 smack_privilege,
366                                 "nfc-manager::tag",
367                                 "w") == false) {
368                 NFC_ERR("permission denied, and finished request");
369
370                 return FALSE;
371         }
372
373         data = g_new0(MakeReadOnlyData, 1);
374         if (data == NULL)
375         {
376                 NFC_ERR("Memory allocation failed");
377                 g_dbus_method_invocation_return_dbus_error(invocation,
378                                 "org.tizen.NetNfcService.AllocationError",
379                                 "Can not allocate memory");
380
381                 return FALSE;
382         }
383
384         data->ndef = g_object_ref(ndef);
385         data->invocation = g_object_ref(invocation);
386         data->handle = arg_handle;
387
388         result = net_nfc_server_controller_async_queue_push(
389                         ndef_make_read_only_thread_func,
390                         data);
391         if (result == FALSE)
392         {
393                 g_dbus_method_invocation_return_dbus_error(invocation,
394                                 "org.tizen.NetNfcService.Ndef.ThreadError",
395                                 "can not push to controller thread");
396
397                 g_object_unref(data->invocation);
398                 g_object_unref(data->ndef);
399
400                 g_free(data);
401         }
402
403         return result;
404 }
405
406 static gboolean ndef_handle_format(NetNfcGDbusNdef *ndef,
407                 GDBusMethodInvocation *invocation,
408                 guint32 arg_handle,
409                 GVariant *arg_key,
410                 GVariant *smack_privilege,
411                 gpointer user_data)
412 {
413         FormatData *data;
414         gboolean result;
415
416         NFC_INFO(">>> REQUEST from [%s]",
417                         g_dbus_method_invocation_get_sender(invocation));
418
419         /* check privilege and update client context */
420         if (net_nfc_server_gdbus_check_privilege(invocation,
421                                 smack_privilege,
422                                 "nfc-manager::tag",
423                                 "w") == false) {
424                 NFC_ERR("permission denied, and finished request");
425
426                 return FALSE;
427         }
428
429         data = g_new0(FormatData, 1);
430         if (data == NULL)
431         {
432                 NFC_ERR("Memory allocation failed");
433                 g_dbus_method_invocation_return_dbus_error(invocation,
434                                 "org.tizen.NetNfcService.AllocationError",
435                                 "Can not allocate memory");
436
437                 return FALSE;
438         }
439
440         data->ndef = g_object_ref(ndef);
441         data->invocation = g_object_ref(invocation);
442         data->handle = arg_handle;
443         net_nfc_util_gdbus_variant_to_data_s(arg_key, &data->key);
444
445         result = net_nfc_server_controller_async_queue_push(
446                         ndef_format_thread_func,
447                         data);
448         if (result == FALSE)
449         {
450                 g_dbus_method_invocation_return_dbus_error(invocation,
451                                 "org.tizen.NetNfcService.Ndef.ThreadError",
452                                 "can not push to controller thread");
453
454                 net_nfc_util_free_data(&data->key);
455
456                 g_object_unref(data->invocation);
457                 g_object_unref(data->ndef);
458
459                 g_free(data);
460         }
461
462         return result;
463 }
464
465 gboolean net_nfc_server_ndef_init(GDBusConnection *connection)
466 {
467         gboolean result;
468         GError *error = NULL;
469
470         if (ndef_skeleton)
471                 net_nfc_server_ndef_deinit();
472
473         ndef_skeleton = net_nfc_gdbus_ndef_skeleton_new();
474
475         g_signal_connect(ndef_skeleton,
476                         "handle-read",
477                         G_CALLBACK(ndef_handle_read),
478                         NULL);
479
480         g_signal_connect(ndef_skeleton,
481                         "handle-write",
482                         G_CALLBACK(ndef_handle_write),
483                         NULL);
484
485         g_signal_connect(ndef_skeleton,
486                         "handle-make-read-only",
487                         G_CALLBACK(ndef_handle_make_read_only),
488                         NULL);
489
490         g_signal_connect(ndef_skeleton,
491                         "handle-format",
492                         G_CALLBACK(ndef_handle_format),
493                         NULL);
494
495         result = g_dbus_interface_skeleton_export(
496                         G_DBUS_INTERFACE_SKELETON(ndef_skeleton),
497                         connection,
498                         "/org/tizen/NetNfcService/Ndef",
499                         &error);
500         if (result == FALSE)
501         {
502                 g_error_free(error);
503
504                 net_nfc_server_ndef_deinit();
505         }
506
507         return TRUE;
508 }
509
510 void net_nfc_server_ndef_deinit(void)
511 {
512         if (ndef_skeleton)
513         {
514                 g_object_unref(ndef_skeleton);
515                 ndef_skeleton = NULL;
516         }
517 }