Fix SVACE issues in bluetooth-frwk
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-tds.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
18 #include <glib.h>
19 #include <gio/gio.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <syspopup_caller.h>
23 #include <vconf.h>
24 #include <bundle_internal.h>
25
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
28
29 #include "bt-service-common.h"
30 #include "bt-service-adapter-le.h"
31 #include "bt-service-event.h"
32 #include "bt-service-adapter.h"
33 #include "bt-service-util.h"
34 #include "bt-service-tds.h"
35
36 #define GATT_SERV_INTERFACE             "org.bluez.GattService1"
37 #define GATT_CHAR_INTERFACE             "org.bluez.GattCharacteristic1"
38 #define GATT_DESC_INTERFACE             "org.bluez.GattDescriptor1"
39
40 #define GATT_DEFAULT_TIMEOUT  (6 * 1000) /* Dependent on supervision timeout 6 sec */
41 #define BT_MAX_DBUS_SENDER_PATH 100
42 #define BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX 15000 /* Timeout for Indication from Provider in msec */
43
44 #define TDS_CONTROL_POINT_RESPONSE_SUCCESS      0x00
45 #define TDS_CONTROL_POINT_RESPONSE_OP_CODE_NOT_SUPPORTED        0x01
46 #define TDS_CONTROL_POINT_RESPONSE_INVALID_PARAMETER    0x02
47 #define TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID   0x03
48 #define TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED     0x04
49
50 #define BT_ADV_FLAG_LEN 3
51 #define TDS_DATA_LEN_MAX        1024
52 #define NUM_TDS_PROVIDER_MAX    10
53
54 typedef enum {
55         BT_AD_TYPE_LOCAL_NAME = 0x09, /**<Complete local name */
56         BT_AD_TYPE_COD = 0x0D, /**< Class of Device */
57         BT_AD_TYPE_MANUF_DATA = 0xFF, /**< Manufacturer data */
58 } bt_advertising_ad_type_e;
59
60 typedef enum {
61         TDS_ROLE_UNSPECIFIED = 0,
62         TDS_ROLE_SEEKER,
63         TDS_ROLE_PROVIDER,
64         TDS_ROLE_SEEKER_PROVIDER
65 } bt_tds_role_t;
66
67 typedef enum {
68         TRANSPORT_DATA_COMPLETE,
69         TRANSPORT_DATA_INCOMPLETE
70 } bt_tds_transport_data_state_t;
71
72 typedef struct {
73         unsigned int tds_handle;
74         bt_tds_role_t role;
75         bluetooth_tds_transport_t transport;
76         bluetooth_tds_transport_state_t state;
77         unsigned int data_len;
78         unsigned char *data;
79 } bt_tds_transport_info_t;
80
81 typedef struct {
82         char *sender;
83         int adv_handle;
84         unsigned int manuf_data_len;
85         unsigned char *manuf_data;
86         GSList *transports;
87 } bt_tds_provider_t;
88
89 /* TDS Activation Request structure */
90 typedef struct {
91         char *remote_address;
92         char *sender;
93         unsigned int activation_timeout_id;
94         int req_id;
95 } bt_tds_activation_info;
96
97 /* TDS transport specific data read Request info structure */
98 typedef struct {
99         char *remote_address;
100         char *sender;
101         int req_id;
102 } bt_tds_data_read_req_info;
103
104 GSList *provider_list = NULL;
105 static int assigned_adv_handle;
106 static gboolean adv_handle_used[NUM_TDS_PROVIDER_MAX];
107
108 #define TDS_MANUF_DATA_LEN_MAX  29
109 static unsigned char manuf_data[TDS_MANUF_DATA_LEN_MAX];
110 static int manuf_data_len;
111
112 static GSList *tds_activation_info_list = NULL;
113 static GSList *tds_data_read_req_info_list = NULL;
114
115 /* Forward declarations */
116 static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address);
117 static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address);
118 static void __bt_tds_send_indication_event(bt_tds_activation_info *info, unsigned char *buffer, int len);
119 static void __bt_tds_remove_indication_info(bt_tds_activation_info *info);
120 static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info);
121
122 static void __bt_init_adv_handle(void)
123 {
124         assigned_adv_handle = 0;
125         memset(adv_handle_used, 0x00, NUM_TDS_PROVIDER_MAX);
126 }
127
128 static int __bt_provider_get_adv_handle(void)
129 {
130         int index;
131
132         index = assigned_adv_handle + 1;
133
134         if (index >= NUM_TDS_PROVIDER_MAX)
135                 index = 0;
136
137         while (adv_handle_used[index] == TRUE) {
138                 if (index == assigned_adv_handle) {
139                         /* No available ID */
140                         BT_ERR("All adv_handles are used");
141                         return -1;
142                 }
143
144                 index++;
145
146                 if (index >= NUM_TDS_PROVIDER_MAX)
147                         index = 0;
148         }
149
150         assigned_adv_handle = index;
151         adv_handle_used[index] = TRUE;
152
153         return assigned_adv_handle;
154 }
155
156 static void __bt_provider_delete_adv_handle(int handle)
157 {
158         ret_if(handle >= NUM_TDS_PROVIDER_MAX);
159         ret_if(handle < 0);
160
161         adv_handle_used[handle] = FALSE;
162 }
163
164 static unsigned char __bt_tds_get_organization_id(int transport)
165 {
166         BT_INFO("transport: %d", transport);
167
168         switch (transport) {
169         case BLUETOOTH_TDS_TRANSPORT_BT:
170                 return 0x01;
171         case BLUETOOTH_TDS_TRANSPORT_CUSTOM:
172                 return 0x02;
173         default:
174                 BT_ERR("Invaid transport");
175                 return 0x00;
176         }
177 }
178
179 static int __bt_tds_get_transport(unsigned char org_id)
180 {
181         BT_INFO("org_id: %d", org_id);
182
183         switch (org_id) {
184         case 0x01:
185                 return BLUETOOTH_TDS_TRANSPORT_BT;
186         case 0x02:
187                 return BLUETOOTH_TDS_TRANSPORT_CUSTOM;
188         default:
189                 BT_ERR("Invaid org_id");
190                 return BLUETOOTH_TDS_TRANSPORT_INVALID;
191         }
192 }
193
194 static unsigned char __bt_tds_set_role(unsigned char flag, bt_tds_role_t role)
195 {
196
197         BT_INFO("Flag: %.2X, Role: %d", flag, role);
198
199         switch (role) {
200         case TDS_ROLE_UNSPECIFIED:
201                 flag = flag & 0xFC;
202                 break;
203         case TDS_ROLE_SEEKER:
204                 flag = flag & 0xFC;
205                 flag = flag | 0x01;
206                 break;
207         case TDS_ROLE_PROVIDER:
208                 flag = flag & 0xFC;
209                 flag = flag | 0x02;
210                 break;
211         case TDS_ROLE_SEEKER_PROVIDER:
212                 flag = flag & 0xFC;
213                 flag = flag | 0x03;
214                 break;
215         default:
216                 BT_ERR("Invalid role received");
217         }
218
219         return flag;
220 }
221
222 static int __bt_tds_get_role(unsigned char flag)
223 {
224
225         BT_INFO("Flag: %.2X", flag);
226
227         if (0x03 == (flag & 0x03))
228                 return TDS_ROLE_SEEKER_PROVIDER;
229         else if (0x02 == (flag & 0x02))
230                 return TDS_ROLE_PROVIDER;
231         else if (0x01 == (flag & 0x01))
232                 return TDS_ROLE_SEEKER;
233         else
234                 return TDS_ROLE_UNSPECIFIED;
235 }
236
237 static unsigned char __bt_tds_set_transport_data_incomplete(
238                 unsigned char flag, gboolean state)
239 {
240         BT_INFO("Flag: %.2X, Data state: %d", flag, state);
241
242         if (state)
243                 flag = flag | 0x04; /* Set incomplete bit to 1 */
244         else
245                 flag = flag & 0xFB; /* Set incomplete bit to 0 */
246
247         return flag;
248 }
249
250 static unsigned char __bt_tds_set_transport_state(
251                 unsigned char flag, bluetooth_tds_transport_state_t state)
252 {
253         BT_INFO("Flag: %.2X, Transport state: %d", flag, state);
254
255         switch (state) {
256         case BLUETOOTH_TDS_TRANSPORT_STATE_OFF:
257                 flag = flag & 0xE7;
258                 break;
259         case BLUETOOTH_TDS_TRANSPORT_STATE_ON:
260                 flag = flag & 0xE7;
261                 flag = flag | 0x08;
262                 break;
263         case BLUETOOTH_TDS_TRANSPORT_STATE_UNAVAILABLE:
264                 flag = flag & 0xE7;
265                 flag = flag | 0x10;
266                 break;
267         case BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED:
268                 flag = flag & 0xE7;
269                 flag = flag | 0x18;
270                 break;
271         default:
272                 BT_ERR("Invalid transport state received");
273         }
274
275         return flag;
276 }
277
278 static unsigned char __bt_tds_get_activation_response_code(int result)
279 {
280         unsigned char resp;
281
282         switch (result) {
283         case BLUETOOTH_ERROR_NONE:
284                 resp = TDS_CONTROL_POINT_RESPONSE_SUCCESS; /* Success */
285                 break;
286         case BLUETOOTH_ERROR_INVALID_PARAM:
287                 resp = TDS_CONTROL_POINT_RESPONSE_INVALID_PARAMETER; /*Invalid Parameter */
288                 break;
289         case BLUETOOTH_ERROR_NOT_SUPPORT:
290                 resp = TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID; /* Unsupported Organization ID*/
291                 break;
292         case BLUETOOTH_ERROR_INTERNAL:
293                 resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED; /* */
294                 break;
295         default:
296                 BT_INFO("Unknown response code: %d received", result);
297                 resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED;
298         }
299
300         return resp;
301 }
302
303 static bt_tds_provider_t* __bt_tds_provider_find_from_list(const char *sender)
304 {
305         GSList *l;
306
307         retv_if(NULL == sender, NULL);
308
309         for (l = provider_list; l != NULL; l = g_slist_next(l)) {
310                 bt_tds_provider_t *provider = l->data;
311                 if (provider && (g_strcmp0(provider->sender, sender) == 0))
312                         return provider;
313         }
314
315         return NULL;
316 }
317
318 static unsigned char* __bt_tds_provider_get_tds_blocks(unsigned int *length)
319 {
320         GSList *l;
321         GSList *l1;
322         unsigned int len = 0;
323         unsigned char data[TDS_DATA_LEN_MAX];
324
325         retv_if(NULL == length, NULL);
326
327         for (l = provider_list; NULL != l; l = g_slist_next(l)) {
328                 bt_tds_provider_t *provider = l->data;
329
330                 if (!provider)
331                         continue;
332
333                 for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
334                         bt_tds_transport_info_t *transport_info = l1->data;
335
336                         if (!transport_info || !transport_info->data)
337                                 continue;
338
339                         if (len + transport_info->data_len > sizeof(data)) {
340                                 BT_ERR("Could not set complete the tds data, size exceeded");
341                                 break;
342                         }
343
344                         memcpy(&(data[len]), transport_info->data, transport_info->data_len);
345                         len += transport_info->data_len;
346                 }
347         }
348
349         *length = len;
350         BT_INFO("length = %d", *length);
351         return g_memdup(data, *length);
352 }
353
354 static void __bt_tds_set_scan_resp_data(bt_tds_provider_t *provider)
355 {
356         bluetooth_scan_resp_data_t scan_resp;
357         char *name = "bt-service";
358         int adv_handle = 0;
359         int len = 0;
360         int ret;
361
362         BT_DBG("+");
363
364         if (provider) {
365                 name = provider->sender;
366                 adv_handle = provider->adv_handle;
367
368                 if (provider->manuf_data_len > 0) {
369                         scan_resp.data[len++] = provider->manuf_data_len + 1;
370                         scan_resp.data[len++] = BT_AD_TYPE_MANUF_DATA;
371                         memcpy(&(scan_resp.data[len]), provider->manuf_data, provider->manuf_data_len);
372                         len += provider->manuf_data_len;
373                 }
374         } else {
375                 if (manuf_data_len > 0) {
376                         scan_resp.data[len++] = manuf_data_len + 1;
377                         scan_resp.data[len++] = BT_AD_TYPE_MANUF_DATA;
378                         memcpy(&(scan_resp.data[len]), manuf_data, manuf_data_len);
379                         len += manuf_data_len;
380                 }
381         }
382
383         if (len <= (BLUETOOTH_SCAN_RESP_DATA_LENGTH_MAX - 2)) {
384                 /* Include name */
385                 scan_resp.data[len++] = 1;
386                 scan_resp.data[len++] = BT_AD_TYPE_LOCAL_NAME;
387         }
388
389         ret = _bt_set_scan_response_data(name, adv_handle, &scan_resp, len, FALSE);
390         if (ret != BLUETOOTH_ERROR_NONE)
391                 BT_ERR("Failed to set_scan response data with error: %d", ret);
392
393         BT_DBG("-");
394 }
395
396 /*
397  * Multi adv not supported (Lagacy device/chip) then, and it is difficult to add all the
398  * tds block in single adv pkt. So for each supported orgId, add only 1 tds blocks with
399  * incomplte tds flag bit set, in adv data.
400  */
401 static int __bt_tds_provider_get_tds_adv_data(guint8 *adv_data)
402 {
403         GSList *l;
404         GSList *l1;
405         unsigned int len = 0;
406         unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN;
407         int transport;
408
409         retv_if(NULL == adv_data, -1);
410
411         adv_data[1] = 0x26;
412         len = 2;
413
414         for (transport = BLUETOOTH_TDS_TRANSPORT_BT;
415                         transport < BLUETOOTH_TDS_TRANSPORT_INVALID; transport++) {
416                 gboolean flag = FALSE;
417
418                 if (len > max_adv_len - 3)
419                         break;
420
421                 for (l = provider_list; l != NULL; l = g_slist_next(l)) {
422                         bt_tds_provider_t *provider = l->data;
423
424                         if (!provider)
425                                 continue;
426
427                         for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
428                                 bt_tds_transport_info_t *transport_info = l1->data;
429
430                                 if (!transport_info || !transport_info->data ||
431                                                 transport_info->transport != transport)
432                                         continue;
433
434                                 adv_data[len++] = transport_info->data[0];    /* Organization Id */
435                                 adv_data[len++] = __bt_tds_set_transport_data_incomplete(
436                                                 transport_info->data[1], TRUE);
437                                 adv_data[len++] = 0;    /* Set Transport data len = 0 */
438                                 flag = true;
439                                 break;
440                         }
441
442                         if (flag)
443                                 break;
444                 }
445         }
446
447         BT_INFO("len = %d", len);
448         if (len <= 2)
449                 return -1; /* No data */
450
451         adv_data[0] = len - 1;
452         return len;
453 }
454
455 /* If multi adv supported set each provider's data in seperate adv slot */
456 static int __bt_tds_provider_get_tds_multi_adv_data(bt_tds_provider_t *provider, guint8 *adv_data)
457 {
458         GSList *l;
459         unsigned int len = 0;
460         unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN;
461         int count;
462
463         retv_if(NULL == provider, -1);
464         retv_if(NULL == adv_data, -1);
465
466         count = g_slist_length(provider->transports);
467         adv_data[1] = 0x26;
468         len = 2;
469
470         for (l = provider->transports; l != NULL; l = g_slist_next(l)) {
471                 bt_tds_transport_info_t *transport_info = l->data;
472
473                 if (!transport_info || !transport_info->data)
474                         continue;
475
476                 if ((len + transport_info->data_len < max_adv_len - 3) ||
477                                 (count <= 1 && (len + transport_info->data_len < max_adv_len))) {
478                         memcpy(&(adv_data[len]), transport_info->data, transport_info->data_len);
479                         len += transport_info->data_len;
480                 } else {
481                         /* Not able to accomodated complete data in adv pkt */
482                         adv_data[len++] = transport_info->data[0];      /* Organization Id */
483                         adv_data[len++] = __bt_tds_set_transport_data_incomplete(
484                                         transport_info->data[1], TRUE);
485                         adv_data[len++] = 0;    /* Set Transport data len = 0 */
486                         break;
487                 }
488
489                 count--;
490         }
491
492         BT_INFO("len = %d", len);
493         if (len <= 2)
494                 return -1; /* No data */
495
496         adv_data[0] = len - 1;
497         return len;
498 }
499
500 static int __bt_tds_set_advertising(bt_tds_provider_t *provider)
501 {
502         bluetooth_advertising_data_t adv;
503         bluetooth_advertising_params_t param;
504         char *name = "bt-service";
505         int adv_handle = 0;
506         int length;
507         int ret;
508         int i;
509
510         BT_DBG("+");
511
512         if (provider) {
513                 name = provider->sender;
514                 adv_handle = provider->adv_handle;
515
516                 /* Get updated TDS advertising data */
517                 length = __bt_tds_provider_get_tds_multi_adv_data(provider, adv.data);
518                 if (0 == length)
519                         BT_INFO("No adv data found, return");
520         } else {
521                 /* No provider is present, no need to enable advertising */
522                 if (0 == g_slist_length(provider_list))
523                         return BLUETOOTH_ERROR_NONE;
524
525                 /* Get updated TDS advertising data */
526                 length = __bt_tds_provider_get_tds_adv_data(adv.data);
527                 if (0 == length)
528                         BT_INFO("No adv data found, return");
529         }
530
531         /* If length <= 0, no need to start advertisement */
532         if (0 >= length)
533                 return BLUETOOTH_ERROR_NONE;
534
535         for (i = 0; i < length; i++)
536                 BT_DBG("adv_data: %.2X", adv.data[i]);
537
538         ret = _bt_set_advertising_data(name, adv_handle, &adv, length, FALSE);
539         if (ret != BLUETOOTH_ERROR_NONE) {
540                 BT_ERR("Failed to set ADV %d", ret);
541                 return ret;
542         }
543
544         /* set scan response data */
545         __bt_tds_set_scan_resp_data(provider);
546
547         param.interval_min = 500;
548         param.interval_max = 500;
549         param.filter_policy = BLUETOOTH_ALLOW_SCAN_CONN_ALL;
550         param.type = BLUETOOTH_ADV_CONNECTABLE;
551
552         ret = _bt_set_custom_advertising(name, adv_handle, TRUE, &param, FALSE);
553         if (ret != BLUETOOTH_ERROR_NONE) {
554                 BT_ERR("Failed to enable advertising with error: %d", ret);
555                 return ret;
556         }
557
558         BT_DBG("-");
559         return BLUETOOTH_ERROR_NONE;
560 }
561
562 static int __bt_tds_disable_advertising(bt_tds_provider_t *provider)
563 {
564         char *name = "bt-service";
565         int adv_handle = 0;
566         int ret;
567
568         BT_DBG("+");
569
570         if (provider) {
571                 name = provider->sender;
572                 adv_handle = provider->adv_handle;
573         }
574
575         /* First try to disable adv in case already advertising */
576         ret = _bt_set_advertising(name, adv_handle, FALSE, FALSE);
577         if (ret != BLUETOOTH_ERROR_NONE) {
578                 BT_ERR("Failed to disable advertising with error: %d", ret);
579                 ret = __bt_tds_set_advertising(provider);
580                 if (ret != BLUETOOTH_ERROR_NONE) {
581                         BT_ERR("Failed to enable advertising with error: %d", ret);
582                         return ret;
583                 }
584         }
585
586         BT_DBG("-");
587         return BLUETOOTH_ERROR_NONE;
588 }
589
590 static int __bt_tds_provider_update_transport_data(bt_tds_provider_t *provider)
591 {
592         GDBusProxy *proxy;
593         GDBusConnection *conn;
594         char *adapter_path = NULL;
595         GError *error = NULL;
596         GVariant *result = NULL;
597         GVariantBuilder *builder;
598         GVariant *temp;
599         unsigned char *buf = NULL;
600         unsigned int length = 0;
601         int i;
602
603         BT_DBG("+");
604
605         conn = _bt_gdbus_get_system_gconn();
606         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
607
608         adapter_path = _bt_get_adapter_path();
609         if (adapter_path == NULL) {
610                 BT_ERR("Could not get adapter path\n");
611                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
612         }
613
614         BT_INFO("Adapter path [%s]", adapter_path);
615         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
616                         NULL, BT_BLUEZ_NAME, adapter_path,
617                         BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
618         g_free(adapter_path);
619         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
620
621         buf = __bt_tds_provider_get_tds_blocks(&length);
622         retv_if(length == 0, BLUETOOTH_ERROR_NONE);
623         retv_if(NULL == buf, BLUETOOTH_ERROR_INTERNAL);
624         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
625         for (i = 0; i < length; i++)
626                 g_variant_builder_add(builder, "y", buf[i]);
627         g_free(buf);
628
629         temp = g_variant_new("ay", builder);
630         g_variant_builder_unref(builder);
631         result = g_dbus_proxy_call_sync(proxy, "SetTdsBlockData",
632                         g_variant_new("(@ay)", temp),
633                         G_DBUS_CALL_FLAGS_NONE, -1,
634                         NULL, &error);
635         g_object_unref(proxy);
636         if (result == NULL) {
637                 if (error != NULL) {
638                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
639                         g_error_free(error);
640                 } else {
641                         BT_ERR("Error occured in Proxy call: SetData");
642                 }
643                 return BLUETOOTH_ERROR_INTERNAL;
644         }
645
646         BT_DBG("-");
647         return BLUETOOTH_ERROR_NONE;
648 }
649
650 static void __bt_free_tds_transport_info(gpointer data, gpointer user_data)
651 {
652         bt_tds_transport_info_t *transport_info = data;
653
654         ret_if(NULL == transport_info);
655
656         BT_DBG("+");
657
658         g_free(transport_info->data);
659         g_free(transport_info);
660
661         BT_DBG("-");
662 }
663
664 static bt_tds_transport_info_t * __bt_tds_find_transport_info(
665                 bt_tds_provider_t *provider, unsigned int handle)
666 {
667         GSList *l;
668
669         retv_if(!provider, NULL);
670
671         for (l = provider->transports; l != NULL; l = g_slist_next(l)) {
672                 bt_tds_transport_info_t *transport_info = l->data;
673
674                 if (!transport_info)
675                         continue;
676
677                 if (transport_info->tds_handle == handle)
678                         return transport_info;
679         }
680
681         return NULL;
682 }
683
684 int _bt_tds_provider_register(const char *sender)
685 {
686         GDBusProxy *proxy;
687         GDBusConnection *conn;
688         char *adapter_path = NULL;
689         GError *error = NULL;
690         GVariant *result = NULL;
691         bt_tds_provider_t *provider;
692
693         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
694
695         BT_DBG("+");
696
697         if (__bt_tds_provider_find_from_list(sender))
698                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
699
700         if (0 == g_slist_length(provider_list)) {
701                 /* Init adv_handle list */
702                 __bt_init_adv_handle();
703
704                 conn = _bt_gdbus_get_system_gconn();
705                 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
706
707                 adapter_path = _bt_get_adapter_path();
708                 if (adapter_path == NULL) {
709                         BT_ERR("Could not get adapter path\n");
710                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
711                 }
712
713                 BT_INFO("Adapter path [%s]", adapter_path);
714                 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
715                                 NULL, BT_BLUEZ_NAME, adapter_path,
716                                 BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
717                 g_free(adapter_path);
718                 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
719
720                 result = g_dbus_proxy_call_sync(proxy, "RegisterTdsProvider",
721                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
722                                 NULL, &error);
723                 g_object_unref(proxy);
724                 if (result == NULL) {
725                         if (error != NULL) {
726                                 BT_ERR("Error occured in Proxy call [%s]", error->message);
727                                 g_error_free(error);
728                         } else {
729                                 BT_ERR("Error occured in Proxy call: RegisterTdsProvider");
730                         }
731                         return BLUETOOTH_ERROR_INTERNAL;
732                 }
733         }
734
735         provider = g_malloc0(sizeof(bt_tds_provider_t));
736         provider->sender = g_strdup(sender);
737         provider->adv_handle = __bt_provider_get_adv_handle();
738         if (0 > provider->adv_handle) {
739                 g_free(provider->sender);
740                 g_free(provider);
741                 return BLUETOOTH_ERROR_INTERNAL;
742         }
743
744         provider_list = g_slist_append(provider_list, provider);
745
746         BT_DBG("-");
747         return BLUETOOTH_ERROR_NONE;
748 }
749
750 int _bt_tds_provider_unregister(const char *sender)
751 {
752         GDBusProxy *proxy;
753         GDBusConnection *conn;
754         char *adapter_path = NULL;
755         GError *error = NULL;
756         GVariant *result = NULL;
757         bt_tds_provider_t *provider = NULL;
758         int ret;
759
760         retv_if(NULL == sender, BLUETOOTH_ERROR_NOT_INITIALIZED);
761
762         BT_DBG("+");
763
764         provider = __bt_tds_provider_find_from_list(sender);
765         if (!provider)
766                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
767
768         if (1 == g_slist_length(provider_list)) {
769                 conn = _bt_gdbus_get_system_gconn();
770                 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
771
772                 adapter_path = _bt_get_adapter_path();
773                 if (adapter_path == NULL) {
774                         BT_ERR("Could not get adapter path\n");
775                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
776                 }
777
778                 BT_INFO("Adapter path [%s]", adapter_path);
779                 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
780                                 NULL, BT_BLUEZ_NAME, adapter_path,
781                                 BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
782
783                 g_free(adapter_path);
784                 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
785
786                 result = g_dbus_proxy_call_sync(proxy, "UnregisterTdsProvider",
787                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
788                                 NULL, &error);
789                 g_object_unref(proxy);
790                 if (result == NULL) {
791                         if (error != NULL) {
792                                 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
793                                 g_error_free(error);
794                         } else {
795                                 BT_ERR("Error occured in Proxy call: UnregisterTdsProvider");
796                         }
797                         return BLUETOOTH_ERROR_INTERNAL;
798                 }
799         }
800
801         if (_bt_is_multi_adv_supported()) {
802                 /* Disable advertisement for sender */
803                 ret = _bt_set_advertising(provider->sender, provider->adv_handle, FALSE, FALSE);
804                 if (ret != BLUETOOTH_ERROR_NONE)
805                         BT_ERR("Failed to disable advertising with error: %d", ret);
806         } else {
807                 /*
808                  * Disable advertising here. Later on receiving advertising disabled event,
809                  * advertising will be enabled again with updated advertising data
810                  */
811                 ret = __bt_tds_disable_advertising(NULL);
812                 if (ret != BLUETOOTH_ERROR_NONE)
813                         BT_ERR("Failed to disable advertising with error: %d", ret);
814         }
815
816         provider_list = g_slist_remove(provider_list, provider);
817         g_slist_foreach(provider->transports, __bt_free_tds_transport_info, NULL);
818         g_slist_free(provider->transports);
819         __bt_provider_delete_adv_handle(provider->adv_handle);
820         g_free(provider->sender);
821         g_free(provider);
822
823         BT_DBG("-");
824         return BLUETOOTH_ERROR_NONE;
825 }
826
827 int _bt_tds_provider_transport_create(const char *sender, int transport, unsigned int tds_handle)
828 {
829         bt_tds_transport_info_t *transport_info;
830         bt_tds_provider_t *provider = NULL;
831
832         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
833
834         if (BLUETOOTH_TDS_TRANSPORT_BT > transport ||
835                         BLUETOOTH_TDS_TRANSPORT_INVALID <= transport) {
836                 BT_ERR("transport value: %d not in range", transport);
837                 return BLUETOOTH_ERROR_INVALID_PARAM;
838         }
839
840         BT_DBG("+");
841
842         provider = __bt_tds_provider_find_from_list(sender);
843         if (!provider)
844                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
845
846         transport_info = g_malloc0(sizeof(bt_tds_transport_info_t));
847         transport_info->transport = transport;
848         transport_info->tds_handle = tds_handle;
849         transport_info->role = TDS_ROLE_PROVIDER;
850         transport_info->state = BLUETOOTH_TDS_TRANSPORT_STATE_OFF;
851         provider->transports = g_slist_append(provider->transports, transport_info);
852
853         BT_DBG("-");
854         return BLUETOOTH_ERROR_NONE;
855 }
856
857 int _bt_tds_provider_transport_remove(const char *sender, unsigned int tds_handle)
858 {
859         bt_tds_provider_t *provider = NULL;
860         bt_tds_transport_info_t *transport_info;
861         int ret;
862
863         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
864
865         BT_DBG("+");
866
867         provider = __bt_tds_provider_find_from_list(sender);
868         if (!provider)
869                 return BLUETOOTH_ERROR_INVALID_PARAM;
870
871         transport_info = __bt_tds_find_transport_info(provider, tds_handle);
872         if (!transport_info)
873                 return BLUETOOTH_ERROR_INVALID_PARAM;
874
875         provider->transports = g_slist_remove(provider->transports, transport_info);
876         __bt_free_tds_transport_info(transport_info, NULL);
877
878         /* Set/update transport data in gatt db */
879         ret = __bt_tds_provider_update_transport_data(provider);
880         if (BLUETOOTH_ERROR_NONE != ret) {
881                 BT_ERR("Failed to update transport data with error: %d", ret);
882                 return ret;
883         }
884
885         /*
886          * Disable advertising here. Later on receiving advertising disabled event,
887          * advertising will be enabled again with updated advertising data.
888          */
889         if (_bt_is_multi_adv_supported())
890                 ret = __bt_tds_disable_advertising(provider);
891         else
892                 ret = __bt_tds_disable_advertising(NULL);
893         if (ret != BLUETOOTH_ERROR_NONE) {
894                 BT_ERR("Failed to enable advertising with error: %d", ret);
895                 return ret;
896         }
897
898         BT_DBG("-");
899         return BLUETOOTH_ERROR_NONE;
900 }
901
902 int _bt_tds_provider_set_manuf_data(char *sender, unsigned char *data, unsigned int len)
903 {
904         bt_tds_provider_t *provider;
905         int ret;
906
907         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
908         retv_if(len == 0 || len > TDS_MANUF_DATA_LEN_MAX, BLUETOOTH_ERROR_INVALID_PARAM);
909         retv_if(NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
910
911         BT_DBG("+");
912
913         BT_INFO("sender: %s", sender);
914         provider = __bt_tds_provider_find_from_list(sender);
915         if (!provider)
916                 return BLUETOOTH_ERROR_INVALID_PARAM;
917
918         /*
919          * Set manufacturer data and disable advertising here. Later on receiving advertising
920          * disabled event, advertising will be enabled again with updated advertising data.
921          */
922         if (_bt_is_multi_adv_supported()) {
923                 g_free(provider->manuf_data);
924                 provider->manuf_data_len = len;
925                 provider->manuf_data = g_malloc0(provider->manuf_data_len);
926                 memcpy(provider->manuf_data, data, len);
927
928                 ret = __bt_tds_disable_advertising(provider);
929         } else {
930                 manuf_data_len = len;
931                 memcpy(manuf_data, data, len);
932                 ret = __bt_tds_disable_advertising(NULL);
933         }
934         if (ret != BLUETOOTH_ERROR_NONE) {
935                 BT_ERR("Failed to enable advertising with error: %d", ret);
936                 return ret;
937         }
938
939         BT_DBG("-");
940         return BLUETOOTH_ERROR_NONE;
941 }
942
943 int _bt_tds_provider_set_transport_data(char *sender, int tds_handle,
944                 int transport_state, unsigned char *data, unsigned int len)
945 {
946         bt_tds_provider_t *provider;
947         bt_tds_transport_info_t *transport_info;
948         int ret;
949
950         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
951         retv_if(len > 0 && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
952
953         BT_DBG("+");
954
955         if (BLUETOOTH_TDS_TRANSPORT_STATE_OFF > transport_state ||
956                         BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED <= transport_state) {
957                 BT_ERR("transport_state value: %d not in range", transport_state);
958                 return BLUETOOTH_ERROR_INVALID_PARAM;
959         }
960
961         BT_INFO("sender: %s, tds_handle: %X", sender, tds_handle);
962         provider = __bt_tds_provider_find_from_list(sender);
963         if (!provider)
964                 return BLUETOOTH_ERROR_INVALID_PARAM;
965
966         transport_info = __bt_tds_find_transport_info(provider, tds_handle);
967         if (!transport_info)
968                 return BLUETOOTH_ERROR_INVALID_PARAM;
969
970         transport_info->state = transport_state;
971         g_free(transport_info->data);
972         transport_info->data_len = len + 3;
973         transport_info->data = g_malloc0(transport_info->data_len);
974         /* TDS Orgnazition Id */
975         transport_info->data[0] = __bt_tds_get_organization_id(transport_info->transport);
976         /* TDS block flag */
977         if (TDS_ROLE_SEEKER_PROVIDER != __bt_tds_get_role(transport_info->data[1]))
978                 transport_info->data[1] = __bt_tds_set_role(transport_info->data[1], transport_info->role);
979         transport_info->data[1] = __bt_tds_set_transport_data_incomplete(transport_info->data[1], FALSE);
980         transport_info->data[1] = __bt_tds_set_transport_state(transport_info->data[1], transport_state);
981         /* TDS block data length */
982         transport_info->data[2] = len;
983         memcpy(&(transport_info->data[3]), data, len);
984
985         /* Set/update transport data in gatt db */
986         ret = __bt_tds_provider_update_transport_data(provider);
987         if (BLUETOOTH_ERROR_NONE != ret) {
988                 BT_ERR("Failed to update transport data with error: %d", ret);
989                 return ret;
990         }
991
992         /*
993          * Disable advertising here. Later on receiving advertising disabled event,
994          * advertising will be enabled again with updated advertising data.
995          */
996         if (_bt_is_multi_adv_supported())
997                 ret = __bt_tds_disable_advertising(provider);
998         else
999                 ret = __bt_tds_disable_advertising(NULL);
1000         if (ret != BLUETOOTH_ERROR_NONE) {
1001                 BT_ERR("Failed to enable advertising with error: %d", ret);
1002                 return ret;
1003         }
1004
1005         BT_DBG("-");
1006         return BLUETOOTH_ERROR_NONE;
1007 }
1008
1009 static int __bt_tds_send_activation_response(char *address,
1010                 unsigned char response, unsigned char *data, unsigned int len)
1011 {
1012         GDBusProxy *proxy;
1013         GDBusConnection *conn;
1014         char *device_path;
1015         GError *error = NULL;
1016         GVariant *result = NULL;
1017         GVariantBuilder *builder;
1018         GVariant *temp;
1019         int i;
1020
1021         retv_if(NULL == address, BLUETOOTH_ERROR_INVALID_PARAM);
1022         retv_if(len > 0 && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
1023
1024         BT_DBG("+");
1025         conn = _bt_gdbus_get_system_gconn();
1026         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1027
1028         device_path = _bt_get_device_object_path(address);
1029         if (NULL == device_path) {
1030                 BT_ERR("Could not get device path\n");
1031                 return BLUETOOTH_ERROR_INTERNAL;
1032         }
1033
1034         BT_INFO("Device path [%s]", device_path);
1035         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1036                         NULL, BT_BLUEZ_NAME, device_path,
1037                         BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
1038         g_free(device_path);
1039         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1040
1041         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1042         for (i = 0; i < len; i++)
1043                 g_variant_builder_add(builder, "y", data[i]);
1044
1045         temp = g_variant_new("ay", builder);
1046         g_variant_builder_unref(builder);
1047         result = g_dbus_proxy_call_sync(proxy, "TdsActivationResponse",
1048                         g_variant_new("(y@ay)", response, temp),
1049                         G_DBUS_CALL_FLAGS_NONE, -1,
1050                         NULL, &error);
1051         g_object_unref(proxy);
1052         if (result == NULL) {
1053                 if (error != NULL) {
1054                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1055                         g_error_free(error);
1056                 } else {
1057                         BT_ERR("Error occured in Proxy call: SetData");
1058                 }
1059                 return BLUETOOTH_ERROR_INTERNAL;
1060         }
1061
1062         BT_DBG("-");
1063         return BLUETOOTH_ERROR_NONE;
1064 }
1065
1066 int _bt_tds_provider_send_activation_response(char *sender, unsigned int tds_handle,
1067         bluetooth_device_address_t *address, int response, unsigned char *data, unsigned int len)
1068 {
1069         bt_tds_provider_t *provider;
1070         bt_tds_transport_info_t *transport_info;
1071         unsigned char resp;
1072         char addr[BT_ADDRESS_STRING_SIZE];
1073         int ret;
1074
1075         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
1076         retv_if(NULL == address, BLUETOOTH_ERROR_INVALID_PARAM);
1077         retv_if(len > 0 && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
1078
1079         BT_DBG("+");
1080
1081         BT_INFO("sender: %s, tds_handle: 0x%X", sender, tds_handle);
1082         provider = __bt_tds_provider_find_from_list(sender);
1083         if (!provider)
1084                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
1085
1086         transport_info = __bt_tds_find_transport_info(provider, tds_handle);
1087         if (!transport_info)
1088                 return BLUETOOTH_ERROR_INVALID_PARAM;
1089
1090         if (BLUETOOTH_ERROR_NONE == response) {
1091                 /* Activation success, set transport state enabled */
1092                 _bt_tds_provider_set_transport_data(provider->sender,
1093                         transport_info->transport, BLUETOOTH_TDS_TRANSPORT_STATE_ON,
1094                         transport_info->data, transport_info->data_len);
1095         }
1096
1097         _bt_convert_addr_type_to_string(addr, address->addr);
1098         resp = __bt_tds_get_activation_response_code(response);
1099
1100         ret = __bt_tds_send_activation_response(addr, resp, data, len);
1101         if (ret != BLUETOOTH_ERROR_NONE) {
1102                 BT_ERR("Failed to send activation response with error: %d", ret);
1103                 return ret;
1104         }
1105
1106         BT_DBG("-");
1107         return BLUETOOTH_ERROR_NONE;
1108 }
1109
1110 void _bt_tds_handle_activation_request(const char *path,
1111                 unsigned char org_id, unsigned char *buf, int len)
1112 {
1113         int transport;
1114         char *address;
1115         GVariant *tds_data;
1116         GVariant *param;
1117         int count = 0;
1118         GSList *l;
1119         GSList *l1;
1120
1121         ret_if(NULL == path);
1122         ret_if(len > 0 && NULL == buf);
1123
1124         BT_DBG("+");
1125
1126         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1127         _bt_convert_device_path_to_address(path, address);
1128         transport = __bt_tds_get_transport(org_id);
1129         BT_DBG("Address: %s, transport: %.2X", address, transport);
1130
1131         if (BLUETOOTH_TDS_TRANSPORT_INVALID == transport)
1132                 goto err;
1133
1134         tds_data = g_variant_new_from_data((const GVariantType *)"ay",
1135                         buf, len, TRUE, NULL, NULL);
1136         param = g_variant_new("(si@ay)", address, transport, tds_data);
1137
1138         /* Find provider with transport type in list and send event to them */
1139         for (l = provider_list; l != NULL; l = g_slist_next(l)) {
1140                 bt_tds_provider_t *provider = l->data;
1141
1142                 if (!provider)
1143                         continue;
1144
1145                 for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
1146                         bt_tds_transport_info_t *transport_info = l1->data;
1147
1148                         if (transport_info && transport_info->transport == transport) {
1149                                 _bt_send_event_to_dest(provider->sender, BT_TDS_EVENT,
1150                                                 BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED, param);
1151                                 count++;
1152                         }
1153                 }
1154         }
1155
1156         /* If no provider found for transport type, send error */
1157         if (0 == count)
1158                 goto err;
1159
1160         BT_DBG("-");
1161         return;
1162 err:
1163         /* send activation response as error to bluez */
1164         __bt_tds_send_activation_response(address,
1165                 TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID, NULL, 0);
1166 }
1167
1168 void _bt_tds_stop_by_terminated_process(char *name)
1169 {
1170         bt_tds_provider_t *provider = NULL;
1171
1172         provider = __bt_tds_provider_find_from_list(name);
1173         if (!provider)
1174                 return;
1175
1176         _bt_tds_provider_unregister(provider->sender);
1177 }
1178
1179 void _bt_tds_handle_adv_disabled(const char *sender, int adv_handle)
1180 {
1181         bt_tds_provider_t *provider = NULL;
1182
1183         BT_INFO("sender: %s, adv_handle:%d", sender, adv_handle);
1184
1185         ret_if(NULL == sender);
1186
1187         if (g_strcmp0(sender, "bt-service") != 0) {
1188                 provider = __bt_tds_provider_find_from_list(sender);
1189                 if (!provider || provider->adv_handle != adv_handle) {
1190                         BT_INFO("Provider not found");
1191                         return;
1192                 }
1193         } else {
1194                 if (adv_handle != 0)
1195                         return;
1196         }
1197
1198         __bt_tds_set_advertising(provider);
1199 }
1200
1201 static void __bt_tds_transport_data_read_desc_cb(GObject *source_object,
1202                         GAsyncResult *res, gpointer user_data)
1203 {
1204         GError *error = NULL;
1205         bt_gatt_char_descriptor_property_t att_value =  { 0, };
1206         GDBusConnection *system_gconn = NULL;
1207         GVariant *value = NULL;
1208         GByteArray *gp_byte_array = NULL;
1209         GVariantIter *iter = NULL;
1210         guint8 g_byte;
1211         bt_tds_data_read_req_info *info = NULL;
1212         GVariant *out_param1;
1213         request_info_t *req_info = NULL;
1214         bluetooth_device_address_t device_addr = { {0} };
1215         int result = BLUETOOTH_ERROR_NONE;
1216         int k;
1217
1218         GVariant *var_data, *param = NULL;
1219         char *tds_data = NULL;
1220         char *address;
1221
1222         BT_DBG("+");
1223         system_gconn = _bt_gdbus_get_system_gconn();
1224
1225         address = (char *)user_data;
1226         info = __bt_tds_data_read_info_by_address(address);
1227
1228         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1229
1230         if (error) {
1231                 BT_ERR("Error : %s \n", error->message);
1232                 g_free(address);
1233                 if (info) {
1234                         req_info = _bt_get_request_info(info->req_id);
1235                         __bt_tds_remove_data_read_req_info(info);
1236                 }
1237                 result = BLUETOOTH_ERROR_INTERNAL;
1238                 goto dbus_return;
1239         }
1240
1241         gp_byte_array = g_byte_array_new();
1242         g_variant_get(value, "(ay)", &iter);
1243
1244         while (g_variant_iter_loop(iter, "y",  &g_byte))
1245                 g_byte_array_append(gp_byte_array, &g_byte, 1);
1246
1247         if (gp_byte_array->len != 0) {
1248                 att_value.val_len = (unsigned int)gp_byte_array->len;
1249                 att_value.val = (unsigned char *)gp_byte_array->data;
1250         }
1251
1252         tds_data = (char *)g_memdup(att_value.val, att_value.val_len);
1253
1254         var_data = g_variant_new_from_data((const GVariantType *)"ay",
1255                         tds_data, att_value.val_len, TRUE, NULL, NULL);
1256
1257         if (info) {
1258                 param = g_variant_new("(isn@ay)", result, address, att_value.val_len, var_data);
1259                 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1260                                 BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED,
1261                                 param);
1262                 req_info = _bt_get_request_info(info->req_id);
1263                 __bt_tds_remove_data_read_req_info(info);
1264         }
1265
1266         /* DEBUG */
1267         for (k = 0; k < att_value.val_len; k++)
1268                 BT_DBG("Transport Data[%d] = [0x%x]", k, att_value.val[k]);
1269
1270 dbus_return:
1271         if (req_info == NULL) {
1272                 BT_ERR("TDS Complete data read Request is not found!!");
1273                 goto done;
1274         }
1275
1276         if (req_info->context == NULL)
1277                 goto done;
1278
1279         _bt_convert_addr_string_to_type(device_addr.addr,
1280                         (const char *)address);
1281
1282         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1283                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1284         g_dbus_method_invocation_return_value(req_info->context,
1285                         g_variant_new("(iv)", result, out_param1));
1286
1287         _bt_delete_request_list(req_info->req_id);
1288
1289 done:
1290         /* Data free */
1291         if (error)
1292                 g_clear_error(&error);
1293         if (gp_byte_array)
1294                 g_byte_array_free(gp_byte_array, TRUE);
1295         if (address)
1296                 g_free(address);
1297         if (value)
1298                 g_variant_unref(value);
1299         if (iter)
1300                 g_variant_iter_free(iter);
1301         if (tds_data)
1302                 g_free(tds_data);
1303         BT_DBG("-");
1304 }
1305
1306 int _bt_tds_read_transport_data(int request_id, char *sender,
1307                 bluetooth_device_address_t *dev_addr, char *handle)
1308 {
1309         GDBusConnection *conn;
1310         char *address = NULL;
1311         bt_tds_data_read_req_info *info = NULL;
1312
1313         BT_CHECK_PARAMETER(handle, return);
1314         BT_CHECK_PARAMETER(sender, return);
1315         BT_CHECK_PARAMETER(dev_addr, return);
1316
1317         conn = _bt_gdbus_get_system_gconn();
1318         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1319
1320         BT_DBG("Read Complete TDS block from Provider [Handle] [%s]", handle);
1321         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1322         _bt_convert_addr_type_to_string(address, dev_addr->addr);
1323
1324         /* If TDS data read already pending on same Provider, then return In progress */
1325         if (__bt_tds_data_read_info_by_address(address) != NULL) {
1326                 BT_ERR("TDS Data Read Req is ongoing in remote provider [%s]", address);
1327                 g_free(address);
1328                 return BLUETOOTH_ERROR_IN_PROGRESS;
1329         }
1330
1331         g_dbus_connection_call(conn,
1332                         BT_BLUEZ_NAME,
1333                         handle,
1334                         GATT_DESC_INTERFACE,
1335                         "ReadValue",
1336                         NULL,
1337                         G_VARIANT_TYPE("(ay)"),
1338                         G_DBUS_CALL_FLAGS_NONE,
1339                         -1,
1340                         NULL,
1341                         (GAsyncReadyCallback)__bt_tds_transport_data_read_desc_cb,
1342                         (gpointer)address);
1343
1344         /* Save Info in pending list */
1345         info = g_malloc0(sizeof(bt_tds_data_read_req_info));
1346         info->remote_address = g_strdup(address);
1347         info->sender = g_strdup(sender);
1348         info->req_id = request_id;
1349         tds_data_read_req_info_list = g_slist_append(tds_data_read_req_info_list, info);
1350
1351         BT_DBG("-");
1352         return BLUETOOTH_ERROR_NONE;
1353 }
1354
1355 static void __bluetooth_internal_control_point_enable_request_cb(GObject *source_object,
1356                         GAsyncResult *res, gpointer user_data)
1357 {
1358         GError *error = NULL;
1359         GDBusConnection *system_gconn = NULL;
1360         GVariant *value = NULL;
1361         GVariant *param = NULL;
1362         GVariant *out_param1 = NULL;
1363         int result = BLUETOOTH_ERROR_NONE;
1364         char *address = NULL;
1365         bt_tds_activation_info *info = NULL;
1366         request_info_t *req_info = NULL;
1367         bluetooth_device_address_t device_addr = { {0} };
1368         BT_DBG("+");
1369
1370         system_gconn = _bt_gdbus_get_system_gconn();
1371         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1372
1373         if (error) {
1374                 BT_ERR("Error : %s \n", error->message);
1375                 if (g_strrstr(error->message, "Already notifying"))
1376                         result = BLUETOOTH_ERROR_NONE;
1377                 else if (g_strrstr(error->message, "In Progress"))
1378                         result = BLUETOOTH_ERROR_IN_PROGRESS;
1379                 else if (g_strrstr(error->message, "Operation is not supported"))
1380                         result = BLUETOOTH_ERROR_NOT_SUPPORT;
1381                 else if (g_strrstr(error->message, "Write not permitted") ||
1382                                 g_strrstr(error->message, "Operation Not Authorized"))
1383                         result = BLUETOOTH_ERROR_PERMISSION_DEINED;
1384                 else if (g_strrstr(error->message, "Not paired"))
1385                         result = BLUETOOTH_ERROR_NOT_PAIRED;
1386                 else
1387                         result = BLUETOOTH_ERROR_INTERNAL;
1388         } else {
1389                 BT_DBG("TDS CCCD enable request successful, send event to BT App");
1390         }
1391
1392         address = (char *)user_data;
1393         info = __bt_tds_activation_info_by_address(address);
1394
1395         if (info)
1396                 req_info = _bt_get_request_info(info->req_id);
1397
1398         /* If CCCD Enable request failed for any reason, reset timer */
1399         if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1400                 BT_ERR("Activation Request failed");
1401                 /* Reset Timer */
1402                 if (info->activation_timeout_id > 0) {
1403                         g_source_remove(info->activation_timeout_id);
1404                         info->activation_timeout_id = 0;
1405                 }
1406
1407                 /* Remove Indication Info */
1408                 __bt_tds_remove_indication_info(info);
1409         } else {
1410                 /* CCCD Enable Request successful */
1411                 if (info) {
1412                         param = g_variant_new("(is)", result, address);
1413                         _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1414                                         BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED,
1415                                         param);
1416                 }
1417         }
1418
1419         if (req_info == NULL) {
1420                 BT_ERR("TDS Control Point CCCD Enable Request is not found!!");
1421                 goto done;
1422         }
1423
1424         if (req_info->context == NULL)
1425                 goto done;
1426
1427         _bt_convert_addr_string_to_type(device_addr.addr,
1428                         (const char *)address);
1429
1430         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1431                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1432         g_dbus_method_invocation_return_value(req_info->context,
1433                         g_variant_new("(iv)", result, out_param1));
1434
1435         _bt_delete_request_list(req_info->req_id);
1436
1437 done:
1438         if (value)
1439                 g_variant_unref(value);
1440         if (error)
1441                 g_clear_error(&error);
1442         if (address)
1443                 g_free(address);
1444
1445         BT_DBG("-");
1446         return;
1447 }
1448
1449 int _bt_tds_enable_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1450                         char *handle)
1451 {
1452         GDBusConnection *conn;
1453         char *address = NULL;
1454         bt_tds_activation_info *info = NULL;
1455
1456         BT_CHECK_PARAMETER(handle, return);
1457         BT_CHECK_PARAMETER(sender, return);
1458         BT_CHECK_PARAMETER(dev_addr, return);
1459
1460         conn = _bt_gdbus_get_system_gconn();
1461         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1462
1463         BT_DBG("TDS Control point CCCD Handle [%s]", handle);
1464
1465         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1466         _bt_convert_addr_type_to_string(address, dev_addr->addr);
1467
1468         if (__bt_tds_activation_info_by_address(address) != NULL) {
1469                 BT_ERR("Activation is already ongoing for same remote provider");
1470                 g_free(address);
1471                 return BLUETOOTH_ERROR_IN_PROGRESS;
1472         }
1473
1474         BT_INFO("Start Notify to Bluez");
1475         g_dbus_connection_call(conn,
1476                         BT_BLUEZ_NAME,
1477                         handle,
1478                         GATT_CHAR_INTERFACE,
1479                         "StartNotify",
1480                         NULL,
1481                         NULL,
1482                         G_DBUS_CALL_FLAGS_NONE,
1483                         GATT_DEFAULT_TIMEOUT, NULL,
1484                         (GAsyncReadyCallback)__bluetooth_internal_control_point_enable_request_cb,
1485                         (gpointer)address);
1486
1487         info = g_malloc0(sizeof(bt_tds_activation_info));
1488         info->remote_address = g_strdup(address);
1489         info->sender = g_strdup(sender);
1490         info->req_id = request_id;
1491         tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1492
1493         BT_DBG("-");
1494         return BLUETOOTH_ERROR_NONE;
1495 }
1496
1497 static void __bluetooth_internal_activation_request_cb(GObject *source_object,
1498                         GAsyncResult *res, gpointer user_data)
1499 {
1500         GError *error = NULL;
1501         GDBusConnection *system_gconn = NULL;
1502         GVariant *value = NULL;
1503         GVariant *param = NULL;
1504         GVariant *out_param1 = NULL;
1505         int result = BLUETOOTH_ERROR_NONE;
1506         guint8 att_ecode = 0;
1507         char *address = NULL;
1508         bt_tds_activation_info *info = NULL;
1509         request_info_t *req_info = NULL;
1510         bluetooth_device_address_t device_addr = { {0} };
1511         BT_DBG("+");
1512
1513         system_gconn = _bt_gdbus_get_system_gconn();
1514         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1515
1516         if (error) {
1517                 BT_ERR("Error : %s \n", error->message);
1518                 result = BLUETOOTH_ERROR_INTERNAL;
1519         } else {
1520                 g_variant_get(value, "(y)", &att_ecode);
1521                 if (att_ecode) {
1522                         result =  BLUETOOTH_ERROR_INTERNAL;
1523                         BT_ERR("ATT Error code: %d \n", att_ecode);
1524                 }
1525         }
1526
1527         address = (char *)user_data;
1528         info = __bt_tds_activation_info_by_address(address);
1529         if (info)
1530                 req_info = _bt_get_request_info(info->req_id);
1531
1532         /* Is Activation request failed for any reason, reset timer */
1533         if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1534                 BT_ERR("Activation Request failed");
1535                 /* Reset Timer */
1536                 if (info->activation_timeout_id > 0) {
1537                         g_source_remove(info->activation_timeout_id);
1538                         info->activation_timeout_id = 0;
1539                 }
1540
1541                 /* Remove Indication Info */
1542                 __bt_tds_remove_indication_info(info);
1543         } else {
1544                 /* Activation Request successful */
1545                 if (info) {
1546                         param = g_variant_new("(is)", result, address);
1547                         _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1548                                         BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT,
1549                                         param);
1550                 }
1551         }
1552
1553         if (req_info == NULL) {
1554                 BT_ERR("TDS Control Point Activation Request is not found!!");
1555                 goto done;
1556         }
1557
1558         if (req_info->context == NULL)
1559                 goto done;
1560
1561         _bt_convert_addr_string_to_type(device_addr.addr,
1562                         (const char *)address);
1563
1564         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1565                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1566         g_dbus_method_invocation_return_value(req_info->context,
1567                         g_variant_new("(iv)", result, out_param1));
1568
1569         _bt_delete_request_list(req_info->req_id);
1570
1571 done:
1572         if (value)
1573                 g_variant_unref(value);
1574         if (error)
1575                 g_clear_error(&error);
1576         if (address)
1577                 g_free(address);
1578
1579         BT_DBG("-");
1580         return;
1581 }
1582
1583 static bool __bt_tds_indication_timeout_cb(gpointer user_data)
1584 {
1585         char *address = NULL;
1586         address = (char*) user_data;
1587         bt_tds_activation_info *info = NULL;
1588         /* Indication:Fail*/
1589         unsigned char buffer[2] = {0x01, 0x04};
1590
1591         BT_DBG("Activation timer Expired [Provider] [%s]", address);
1592
1593         info = __bt_tds_activation_info_by_address(address);
1594         if (info)
1595                 __bt_tds_send_indication_event(info, buffer, sizeof(buffer));
1596         return FALSE;
1597 }
1598
1599 int _bt_tds_activate_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1600                                         char *handle, unsigned char *param, int length)
1601 {
1602         GVariant *val;
1603         GVariantBuilder *builder;
1604         int i;
1605         bt_tds_activation_info *info = NULL;
1606         GDBusConnection *conn;
1607         char *address = NULL;
1608         BT_DBG("+");
1609
1610         BT_CHECK_PARAMETER(handle, return);
1611         BT_CHECK_PARAMETER(sender, return);
1612         BT_CHECK_PARAMETER(dev_addr, return);
1613         BT_CHECK_PARAMETER(param, return);
1614
1615         conn = _bt_gdbus_get_system_gconn();
1616         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1617
1618         BT_DBG("TDS Control point Activate handle [%s] data length [%d]", handle, length);
1619         /* Check if activation is ongoing for the same Remote Provider */
1620         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1621         _bt_convert_addr_type_to_string(address, dev_addr->addr);
1622
1623         info = __bt_tds_activation_info_by_address(address);
1624         if (info && info->activation_timeout_id > 0) {
1625                 BT_ERR("Activation is already ongoing in remote provider");
1626                 g_free(address);
1627                 return BLUETOOTH_ERROR_IN_PROGRESS;
1628         }
1629
1630         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1631
1632         for (i = 0; i < length; i++)
1633                 g_variant_builder_add(builder, "y", param[i]);
1634
1635         val = g_variant_new("(ay)", builder);
1636
1637         /* Activate Control Point */
1638         g_dbus_connection_call(conn,
1639                         BT_BLUEZ_NAME,
1640                         handle,
1641                         GATT_CHAR_INTERFACE,
1642                         "WriteValue",
1643                         val,
1644                         G_VARIANT_TYPE("(y)"),
1645                         G_DBUS_CALL_FLAGS_NONE,
1646                         -1, NULL,
1647                         (GAsyncReadyCallback)__bluetooth_internal_activation_request_cb,
1648                         (gpointer)address);
1649
1650         g_variant_builder_unref(builder);
1651
1652         if (info == NULL) {
1653                 info = g_malloc0(sizeof(bt_tds_activation_info));
1654                 info->remote_address = g_strdup(address);
1655                 info->sender = g_strdup(sender);
1656                 tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1657         }
1658         info->req_id = request_id;
1659         info->activation_timeout_id = g_timeout_add(BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX,
1660                         (GSourceFunc)__bt_tds_indication_timeout_cb, (gpointer)info->remote_address);
1661
1662         BT_DBG("-");
1663         return BLUETOOTH_ERROR_NONE;
1664 }
1665
1666 static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address)
1667 {
1668         GSList *l;
1669         bt_tds_activation_info *info = NULL;
1670
1671         for (l = tds_activation_info_list; l != NULL; l = g_slist_next(l)) {
1672                 info = (bt_tds_activation_info*)l->data;
1673                 if (info == NULL)
1674                         continue;
1675
1676                 if (!g_strcmp0(info->remote_address, address)) {
1677                         BT_INFO("Seeker found waiting for Ind from Provider addr[%s]",
1678                                         info->remote_address);
1679                         return info;
1680                 }
1681         }
1682         return NULL;
1683 }
1684
1685 static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address)
1686 {
1687         GSList *l;
1688         bt_tds_data_read_req_info *info = NULL;
1689
1690         for (l = tds_data_read_req_info_list; l != NULL; l = g_slist_next(l)) {
1691                 info = (bt_tds_data_read_req_info*)l->data;
1692                 if (info == NULL)
1693                         continue;
1694
1695                 if (!g_strcmp0(info->remote_address, address)) {
1696                         BT_INFO("Found waiting for Transport Data Read from Provider addr[%s]",
1697                                         info->remote_address);
1698                         return info;
1699                 }
1700         }
1701         return NULL;
1702 }
1703
1704 static void __bt_tds_remove_indication_info(bt_tds_activation_info *info)
1705 {
1706         BT_DBG("Removing Indication Info [%s]", info->remote_address);
1707
1708         tds_activation_info_list = g_slist_remove(tds_activation_info_list, info);
1709         if (info->remote_address)
1710                 g_free(info->remote_address);
1711         if (info->sender)
1712                 g_free(info->sender);
1713         if (info->activation_timeout_id > 0) {
1714                 g_source_remove(info->activation_timeout_id);
1715                 info->activation_timeout_id = 0;
1716         }
1717         g_free(info);
1718 }
1719
1720 static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info)
1721 {
1722         BT_DBG("Removing Read Req Info [%s]", info->remote_address);
1723
1724         tds_data_read_req_info_list = g_slist_remove(tds_data_read_req_info_list, info);
1725         if (info->remote_address)
1726                 g_free(info->remote_address);
1727         if (info->sender)
1728                 g_free(info->sender);
1729         g_free(info);
1730 }
1731
1732 static void __bt_tds_send_indication_event(bt_tds_activation_info *info,
1733                                                 unsigned char *buffer, int len)
1734 {
1735         GVariant *tds_data;
1736         GVariant *param;
1737
1738         tds_data = g_variant_new_from_data((const GVariantType *)"ay",
1739                         buffer, len, TRUE, NULL, NULL);
1740
1741         BT_DBG("Send Indication event to sender");
1742         param = g_variant_new("(s@ay)", info->remote_address, tds_data);
1743         _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1744                                         BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION,
1745                                         param);
1746
1747         /* Remove info from list */
1748         __bt_tds_remove_indication_info(info);
1749 }
1750
1751 void _bt_tds_check_indication(const char *path, GVariant *msg)
1752 {
1753         char address[BT_ADDRESS_STRING_SIZE] = {0};
1754         bt_tds_activation_info *info = NULL;
1755         unsigned char *buffer = NULL;
1756         int len = 0;
1757         int i;
1758         GVariant *value = NULL;
1759         BT_DBG("+");
1760
1761         _bt_convert_device_path_to_address(path, address);
1762         info = __bt_tds_activation_info_by_address(address);
1763
1764         if (info) {
1765                 g_variant_get(msg, "(is@ay)", NULL, NULL, &value);
1766                 len = g_variant_get_size(value);
1767                 BT_DBG("Indication data from Provider len[%d]", len);
1768                 if (len > 0) {
1769                         buffer = (unsigned char *)g_variant_get_data(value);
1770                         /* DEBUG */
1771                         for (i = 0; i < len; i++)
1772                                 BT_DBG("%.2x", buffer[i]);
1773                 }
1774
1775                 /* Reset Timer */
1776                 if (info->activation_timeout_id > 0)
1777                         g_source_remove(info->activation_timeout_id);
1778
1779                 /* Send Indication & info removed internally */
1780                 __bt_tds_send_indication_event(info, buffer, len);
1781                 g_variant_unref(value);
1782         }
1783         BT_DBG("-");
1784 }