Get the latest NFC state from neard
[platform/core/connectivity/nfc-manager-neard.git] / daemon / net_nfc_server_p2p.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_debug_internal.h"
18 #include "net_nfc_util_internal.h"
19 #include "net_nfc_util_gdbus_internal.h"
20 #include "net_nfc_server_controller.h"
21 #include "net_nfc_gdbus.h"
22 #include "net_nfc_server_common.h"
23 #include "net_nfc_server_tag.h"
24 #include "net_nfc_server_context.h"
25 #include "net_nfc_server_process_snep.h"
26 #include "net_nfc_server_p2p.h"
27
28
29 typedef struct _P2pSendData P2pSendData;
30
31 struct _P2pSendData
32 {
33         NetNfcGDbusP2p *p2p;
34         GDBusMethodInvocation *invocation;
35         gint32 type;
36         guint32 p2p_handle;
37         data_s data;
38 };
39
40 static NetNfcGDbusP2p *p2p_skeleton = NULL;
41
42 static void p2p_send_data_thread_func(gpointer user_data)
43 {
44         net_nfc_error_e result;
45         net_nfc_target_handle_s *handle;
46         P2pSendData *p2p_data = user_data;
47
48         g_assert(p2p_data != NULL);
49         g_assert(p2p_data->p2p != NULL);
50         g_assert(p2p_data->invocation != NULL);
51
52         handle = GUINT_TO_POINTER(p2p_data->p2p_handle);
53
54         result = net_nfc_server_snep_default_client_start(handle, SNEP_REQ_PUT,
55                         &p2p_data->data, -1, p2p_data);
56         if (result != NET_NFC_OK)
57         {
58                 net_nfc_gdbus_p2p_complete_send(p2p_data->p2p, p2p_data->invocation, (gint)result);
59
60                 net_nfc_util_free_data(&p2p_data->data);
61
62                 g_object_unref(p2p_data->invocation);
63                 g_object_unref(p2p_data->p2p);
64
65                 g_free(p2p_data);
66         }
67 }
68
69 static gboolean p2p_handle_send(NetNfcGDbusP2p *p2p,
70                 GDBusMethodInvocation *invocation,
71                 gint32 arg_type,
72                 GVariant *arg_data,
73                 guint32 handle,
74                 GVariant *smack_privilege,
75                 gpointer user_data)
76 {
77         bool ret;
78         gboolean result;
79         P2pSendData *data;
80
81         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
82
83         /* check privilege and update client context */
84         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
85                                 "nfc-manager::p2p", "w");
86         if (false == ret)
87         {
88                 NFC_ERR("permission denied, and finished request");
89
90                 return FALSE;
91         }
92
93         data = g_new0(P2pSendData, 1);
94         if(NULL == data)
95         {
96                 NFC_ERR("Memory allocation failed");
97                 g_dbus_method_invocation_return_dbus_error(invocation,
98                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
99
100                 return FALSE;
101         }
102
103         data->p2p = g_object_ref(p2p);
104         data->invocation = g_object_ref(invocation);
105         data->type = arg_type;
106         data->p2p_handle = handle;
107         net_nfc_util_gdbus_variant_to_data_s(arg_data, &data->data);
108
109         result = net_nfc_server_controller_async_queue_push(p2p_send_data_thread_func, data);
110
111         if (FALSE == result)
112         {
113                 g_dbus_method_invocation_return_dbus_error(invocation,
114                                 "org.tizen.NetNfcService.P2p.ThreadError",
115                                 "can not push to controller thread");
116
117                 net_nfc_util_free_data(&data->data);
118
119                 g_object_unref(data->invocation);
120                 g_object_unref(data->p2p);
121
122                 g_free(data);
123         }
124
125         return result;
126 }
127
128
129 gboolean net_nfc_server_p2p_init(GDBusConnection *connection)
130 {
131         gboolean result;
132         GError *error = NULL;
133
134         if (p2p_skeleton)
135                 net_nfc_server_p2p_deinit();
136
137         p2p_skeleton = net_nfc_gdbus_p2p_skeleton_new();
138
139         g_signal_connect(p2p_skeleton, "handle-send", G_CALLBACK(p2p_handle_send), NULL);
140
141         result = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(p2p_skeleton),
142                         connection, "/org/tizen/NetNfcService/P2p", &error);
143         if (FALSE == result)
144         {
145                 g_error_free(error);
146
147                 net_nfc_server_p2p_deinit();
148         }
149
150         return result;
151 }
152
153 void net_nfc_server_p2p_deinit(void)
154 {
155         if (p2p_skeleton)
156         {
157                 g_object_unref(p2p_skeleton);
158                 p2p_skeleton = NULL;
159         }
160 }
161
162 void net_nfc_server_p2p_detached(void)
163 {
164         NFC_INFO("====== p2p target detached ======");
165
166         /* release target information */
167         net_nfc_server_free_target_info();
168
169         if (p2p_skeleton != NULL)
170                 net_nfc_gdbus_p2p_emit_detached(p2p_skeleton);
171 }
172
173 void net_nfc_server_p2p_discovered(net_nfc_target_handle_s *handle)
174 {
175         NFC_INFO("====== p2p target discovered ======");
176
177         if (NULL == p2p_skeleton)
178         {
179                 NFC_ERR("p2p_skeleton is not initialized");
180
181                 return;
182         }
183
184         net_nfc_gdbus_p2p_emit_discovered(p2p_skeleton, GPOINTER_TO_UINT(handle));
185 }
186
187 void net_nfc_server_p2p_received(data_s *user_data)
188 {
189         GVariant *arg_data;
190
191         if (NULL == p2p_skeleton)
192         {
193                 NFC_ERR("p2p_skeleton is not initialized");
194
195                 return;
196         }
197
198         arg_data = net_nfc_util_gdbus_data_to_variant((data_s *)user_data);
199
200         net_nfc_gdbus_p2p_emit_received(p2p_skeleton, arg_data);
201 }
202
203 void net_nfc_server_p2p_data_sent(net_nfc_error_e result, gpointer user_data)
204 {
205         P2pSendData *data = user_data;
206
207         g_assert(data != NULL);
208         g_assert(data->p2p != NULL);
209         g_assert(data->invocation != NULL);
210
211         net_nfc_gdbus_p2p_complete_send(data->p2p, data->invocation, (gint)result);
212
213         net_nfc_util_free_data(&data->data);
214
215         g_object_unref(data->invocation);
216         g_object_unref(data->p2p);
217
218         g_free(data);
219 }