1fd52f5144e59a1ec3ce051dd3f089036f1c9410
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / ipsp / bt-service-ipsp-event-receiver.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 <glib.h>
18 #include <string.h>
19 #include <dlog.h>
20 #include <vconf.h>
21 #include <vconf-internal-bt-keys.h>
22
23 #include "bluetooth-api.h"
24 #include "bt-internal-types.h"
25
26 #include "bt-service-common.h"
27 #include "bt-service-event.h"
28 #include "bt-service-main.h"
29 #include "bt-service-core-adapter.h"
30 #include "bt-service-core-adapter-le.h"
31 #include "bt-service-device.h"
32
33 #ifdef TIZEN_FEATURE_BT_DPM
34 #include "bt-service-dpm.h"
35 #endif
36
37 #define BT_MEDIA_OBJECT_PATH "/Musicplayer"
38 static GDBusConnection *manager_conn;
39
40
41
42 static void __bt_ipsp_property_changed_event(GVariant *msg, const char *path);
43
44
45 static void __bt_device_property_changed_event(GVariant *msg, const char *path)
46 {
47         int event;
48         int result = BLUETOOTH_ERROR_NONE;
49         GVariantIter value_iter;
50         GVariant *val;
51         char *property = NULL;
52         char *address;
53         GVariant *param = NULL;
54         g_variant_iter_init(&value_iter, msg);
55
56         while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val))) {
57                 BT_DBG("Property %s", property);
58                 if (strcasecmp(property, "IpspConnected") == 0) {
59                         gboolean connected = FALSE;
60
61                         g_variant_get(val, "b", &connected);
62
63
64                         event = connected ? BLUETOOTH_EVENT_IPSP_CONNECTED :
65                                                         BLUETOOTH_EVENT_IPSP_DISCONNECTED;
66
67                         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
68
69                         _bt_convert_device_path_to_address(path, address);
70
71                         BT_DBG("Ipspconnected: %d", connected);
72                         BT_DBG("address: %s", address);
73                         param = g_variant_new("(is)", result, address);
74
75                         /* Send event to application */
76                         _bt_send_event(BT_DEVICE_EVENT,
77                                         event,
78                                         param);
79                         g_free(address);
80                 } else if (strcasecmp(property, "IpspBtInterfaceInfo") == 0) {
81                         char *ifname = NULL;
82
83                         g_variant_get(val, "s", &ifname);
84
85                         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
86
87                         _bt_convert_device_path_to_address(path, address);
88
89                         BT_DBG("Ipsp BT Interface Name: %s", ifname);
90                         BT_DBG("address: %s", address);
91                         param = g_variant_new("(iss)", result, address, ifname);
92
93                         /* Send event to application */
94                         _bt_send_event(BT_DEVICE_EVENT,
95                                         BLUETOOTH_EVENT_IPSP_INTERFACE_INFO,
96                                         param);
97                         g_free(address);
98                 }
99         }
100 }
101
102 void _bt_handle_ipsp_device_event(GVariant *msg, const char *member, const char *path)
103 {
104         int event = 0;
105         int result = BLUETOOTH_ERROR_NONE;
106         char *address;
107         GVariant *param = NULL;
108         ret_if(path == NULL);
109
110         if  (strcasecmp(member, "IpspStateChanged") == 0) {
111                 gboolean connected = FALSE;
112                 char *ifname = NULL;
113                 GVariant *ipsp_param = NULL;
114
115                 g_variant_get(msg, "(bs)", &connected, &ifname);
116
117                 event = connected ? BLUETOOTH_EVENT_IPSP_CONNECTED :
118                                                 BLUETOOTH_EVENT_IPSP_DISCONNECTED;
119
120                 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
121                 _bt_convert_device_path_to_address(path, address);
122
123                 BT_DBG("Ipsp BT Interface Name: %s, address: %s", ifname, address);
124
125                 param = g_variant_new("(iss)", result, address, ifname);
126                 ipsp_param = g_variant_new("(ss)", ifname, address);
127
128                 g_free(ifname);
129
130                 /* Set Ipv6 Addr */
131                 GDBusProxy *ipsp_proxy;
132                 if (connected) {
133                         BT_DBG("IPSP connected, Set Ipv6 Addr");
134                         ipsp_proxy = _bt_get_ipsp_proxy();
135                         if (ipsp_proxy == NULL) {
136                                 BT_ERR("can not get ipsp proxy");
137                                 g_free(address);
138                                 g_variant_unref(param);
139                                 g_variant_unref(ipsp_param);
140                                 return;
141                         }
142
143                         g_dbus_proxy_call(ipsp_proxy, "SetIpv6Addr",
144                                         ipsp_param, G_DBUS_CALL_FLAGS_NONE,
145                                         -1, NULL, NULL, NULL);
146                 } else {
147                         g_variant_unref(ipsp_param);
148                         BT_DBG("IPSP disconnected");
149                         ipsp_proxy = _bt_get_ipsp_proxy();
150                         if (ipsp_proxy == NULL) {
151                                 BT_ERR("can not get ipsp proxy");
152                                 g_free(address);
153                                 g_variant_unref(param);
154                                 return;
155                         }
156
157                         g_dbus_proxy_call(ipsp_proxy, "DisableIpsp",
158                                         NULL, G_DBUS_CALL_FLAGS_NONE,
159                                         -1, NULL, NULL, NULL);
160                 }
161
162                 /* Send event to application */
163                 _bt_send_event(BT_DEVICE_EVENT, event, param);
164                 g_free(address);
165         }
166 }
167
168
169 static  void __bt_manager_event_filter(GDBusConnection *connection,
170                                         const gchar *sender_name,
171                                         const gchar *object_path,
172                                         const gchar *interface_name,
173                                         const gchar *signal_name,
174                                         GVariant *parameters,
175                                         gpointer user_data)
176 {
177         const char *path = object_path;
178
179         if (signal_name == NULL)
180                 return;
181
182         if (g_strcmp0(interface_name, BT_PROPERTIES_INTERFACE) == 0) {
183                 char *inf_name = NULL;
184                 GVariant *val = NULL;
185
186                 if (strncmp(path, BT_MEDIA_OBJECT_PATH,
187                                 strlen(BT_MEDIA_OBJECT_PATH)) == 0)
188                         return;
189
190                 g_variant_get(parameters, "(&s@a{sv}@as)", &inf_name, &val, NULL);
191
192                 if (strcasecmp(inf_name, BT_ADAPTER_INTERFACE) == 0)
193                         __bt_ipsp_property_changed_event(val, object_path);
194                 else if (strcasecmp(inf_name, BT_DEVICE_INTERFACE) == 0)
195                         __bt_device_property_changed_event(val, object_path);
196
197                 if (val)
198                         g_variant_unref(val);
199         } else if (g_strcmp0(interface_name, BT_DEVICE_INTERFACE) == 0) {
200                         _bt_handle_ipsp_device_event(parameters, signal_name, object_path);
201         }
202
203         return;
204 }
205
206
207 int _bt_register_ipsp_subscribe_signal(GDBusConnection *conn,
208                 int subscribe)
209 {
210
211         if (conn == NULL)
212                 return -1;
213
214         static int subs_interface_added_id = -1;
215         static int subs_interface_removed_id = -1;
216         static int subs_property_id = -1;
217         static int subs_ipsp_state_id = -1;
218
219
220         if (subscribe) {
221                 if (subs_interface_added_id == -1) {
222                         subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
223                                 NULL, BT_MANAGER_INTERFACE,
224                                 BT_INTERFACES_ADDED, NULL, NULL, 0,
225                                 __bt_manager_event_filter,
226                                 NULL, NULL);
227                 }
228                 if (subs_interface_removed_id == -1) {
229                         subs_interface_removed_id = g_dbus_connection_signal_subscribe(conn,
230                                 NULL, BT_MANAGER_INTERFACE,
231                                 BT_INTERFACES_REMOVED, NULL, NULL, 0,
232                                 __bt_manager_event_filter,
233                                 NULL, NULL);
234                 }
235                 if (subs_property_id == -1) {
236                         subs_property_id = g_dbus_connection_signal_subscribe(conn,
237                                 NULL, BT_PROPERTIES_INTERFACE,
238                                 BT_PROPERTIES_CHANGED, NULL, NULL, 0,
239                                 __bt_manager_event_filter,
240                                 NULL, NULL);
241                 }
242                 if (subs_ipsp_state_id == -1) {
243                         subs_ipsp_state_id = g_dbus_connection_signal_subscribe(conn,
244                                 NULL, BT_DEVICE_INTERFACE,
245                                 BT_IPSP_STATE_CHANGE, NULL, NULL, 0,
246                                 __bt_manager_event_filter,
247                                 NULL, NULL);
248                 }
249         } else {
250                 if (subs_interface_added_id != -1) {
251                         g_dbus_connection_signal_unsubscribe(conn,
252                                         subs_interface_added_id);
253                         subs_interface_added_id = -1;
254                 }
255                 if (subs_interface_removed_id != -1) {
256                         g_dbus_connection_signal_unsubscribe(conn,
257                                         subs_interface_removed_id);
258                         subs_interface_removed_id = -1;
259                 }
260                 if (subs_property_id != -1) {
261                         g_dbus_connection_signal_unsubscribe(conn,
262                                         subs_property_id);
263                         subs_property_id = -1;
264                 }
265                 if (subs_ipsp_state_id != -1) {
266                         g_dbus_connection_signal_unsubscribe(conn,
267                                         subs_ipsp_state_id);
268                         subs_ipsp_state_id = -1;
269                 }
270         }
271         return 0;
272 }
273
274 int _bt_init_ipsp_receiver(void)
275 {
276         BT_DBG("+");
277
278         GError *error = NULL;
279
280         if (manager_conn == NULL) {
281                 manager_conn =  g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
282                 if (error != NULL) {
283                         BT_ERR("ERROR: Can't get on system bus [%s]", error->message);
284                         g_clear_error(&error);
285                 }
286                 retv_if(manager_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
287         }
288
289         if (_bt_register_ipsp_subscribe_signal(manager_conn, TRUE) != BLUETOOTH_ERROR_NONE)
290                 goto fail;
291
292         return BLUETOOTH_ERROR_NONE;
293 fail:
294         if (manager_conn) {
295                 g_object_unref(manager_conn);
296                 manager_conn = NULL;
297         }
298
299         BT_DBG("-");
300
301         return BLUETOOTH_ERROR_INTERNAL;
302 }
303
304 void _bt_deinit_service_event_receiver(void)
305 {
306         BT_DBG("+");
307
308         _bt_register_ipsp_subscribe_signal(manager_conn, FALSE);
309
310         if (manager_conn) {
311                 g_object_unref(manager_conn);
312                 manager_conn = NULL;
313         }
314
315         BT_DBG("-");
316 }
317
318 static void __bt_ipsp_property_changed_event(GVariant *msg, const char *path)
319 {
320         GVariantIter value_iter;
321         GVariant *val = NULL;
322         char *property = NULL;
323         GVariant *param = NULL;
324         g_variant_iter_init(&value_iter, msg);
325         while ((g_variant_iter_loop(&value_iter, "{sv}", &property, &val))) {
326                 if (strcasecmp(property, "IpspInitStateChanged") == 0) {
327                         gboolean ipsp_initialized = FALSE;
328
329                         g_variant_get(val, "b", &ipsp_initialized);
330                         BT_INFO("IPSP init state changed: %d", ipsp_initialized);
331                         param = g_variant_new("(b)", ipsp_initialized);
332
333                         /* Send event to application */
334                         _bt_send_event(BT_ADAPTER_EVENT,
335                                         BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED,
336                                         param);
337                 }
338         }
339 }