4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <dbus/dbus.h>
25 #include <notification.h>
28 #include <bundle_internal.h>
31 #include "bluetooth-api.h"
32 #include "bt-share-main.h"
33 #include "bt-share-ipc.h"
34 #include "bt-share-syspopup.h"
35 #include "bt-share-notification.h"
36 #include "bt-share-resource.h"
37 #include "obex-event-handler.h"
38 #include "bluetooth-share-api.h"
39 #include "bt-share-common.h"
40 #include "bt-share-cynara.h"
42 #define FILEPATH_LEN_MAX 4096
44 GSList *bt_transfer_list = NULL;
45 DBusConnection *dbus_connection = NULL;
47 extern struct bt_appdata *app_state;
49 static void __bt_create_send_data(opc_transfer_info_t *node);
51 static void __bt_share_update_tr_info(int tr_uid, int tr_type);
53 static void __bt_tr_data_free(bt_tr_data_t *data)
55 retm_if(data == NULL, "Invalid param");
57 g_free(data->file_path);
58 g_free(data->dev_name);
61 g_free(data->content);
65 static void __popup_res_cb(int res)
68 struct bt_appdata *ad = app_state;
69 if (ad->popups.syspopup_request == FALSE) {
70 DBG("This event is not mine\n");
73 DBG(" res : %d\n", res);
74 /* Inorder to support calling popup from callback, we have to make
75 * syspopup_request false here and also should not assign
76 * ad->popups.popup_cb = NULL */
78 ad->popups.syspopup_request = FALSE;
80 if (NULL != ad->popups.popup_cb) {
82 ad->popups.popup_cb(ad->popups.popup_cb_data,
84 (void *)POPUP_RESPONSE_OK);
86 ad->popups.popup_cb(ad->popups.popup_cb_data,
88 (void *)POPUP_RESPONSE_CANCEL);
90 ad->popups.popup_cb(ad->popups.popup_cb_data,
92 (void *)POPUP_RESPONSE_TIMEOUT);
98 static opc_transfer_info_t *__add_transfer_info(DBusMessage *msg)
104 char *filepath = NULL;
108 opc_transfer_info_t *data;
113 retv_if(msg == NULL, NULL);
114 dbus_message_get_args(msg, NULL,
115 DBUS_TYPE_INT32, &reserved,
116 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
118 DBUS_TYPE_INT32, &cnt,
119 DBUS_TYPE_STRING, &filepath,
120 DBUS_TYPE_STRING, &mode,
121 DBUS_TYPE_STRING, &name,
122 DBUS_TYPE_STRING, &type,
125 retv_if(cnt <= 0, NULL);
126 retv_if(addr == NULL, NULL);
127 retv_if(filepath == NULL, NULL);
128 retv_if(name == NULL, NULL);
130 DBG("reserved ( %d )\n", reserved);
131 DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", addr[0],
132 addr[1], addr[2], addr[3], addr[4], addr[5]);
133 DBG(" cnt( %d )\n", cnt);
134 DBG(" filepath( %s )\n", filepath);
135 DBG(" mode ( %s )\n", mode);
136 DBG(" name ( %s )\n", name);
137 DBG(" type ( %s )\n", type);
139 data = g_new0(opc_transfer_info_t, 1);
141 data->content = g_new0(char *, cnt + 1);
142 data->file_path = g_new0(char *, cnt + 1);
143 data->file_cnt = cnt;
144 memcpy(data->addr, addr, BLUETOOTH_ADDRESS_LENGTH);
145 memcpy(data->name, name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
146 data->type = g_strdup(type);
148 token = strtok_r(filepath, FILE_PATH_DELIM, &ptr);
149 while ((token != NULL) && (i < cnt)) {
150 if (g_strcmp0(type, "text") == 0) {
151 data->file_path[i] = _bt_share_create_transfer_file(token);
153 data->file_path[i] = g_strdup(token);
156 DBG(" file path ( %s )\n", data->file_path[i]);
158 data->content[i] = g_strdup(token);
159 DBG("Content [%d] [%s]\n", i, data->content[i]);
162 token = strtok_r(NULL, FILE_PATH_DELIM, &ptr);
165 bt_transfer_list = g_slist_append(bt_transfer_list, data);
171 void _free_transfer_info(opc_transfer_info_t *node)
176 ret_if(node == NULL);
178 for (i = 0; i < node->file_cnt; i++) {
179 _bt_remove_tmp_file(node->file_path[i]);
180 g_free(node->file_path[i]);
181 g_free(node->content[i]);
183 g_free(node->file_path);
184 g_free(node->content);
191 void _remove_transfer_info(opc_transfer_info_t *node)
194 ret_if(node == NULL);
196 bt_transfer_list = g_slist_remove(bt_transfer_list, node);
197 _free_transfer_info(node);
202 int _request_file_send(opc_transfer_info_t *node)
204 struct bt_appdata *ad = app_state;
207 retv_if(ad == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
208 retv_if(node == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
210 ret = bluetooth_opc_push_files((bluetooth_device_address_t *)node->addr,
212 if (ret != BLUETOOTH_ERROR_NONE) {
213 DBG("bluetooth_opc_push_files failed : %d", ret);
217 __bt_create_send_data(node);
220 return BLUETOOTH_ERROR_NONE;
223 static int __bt_get_owner_info(DBusMessage *msg, char **name,
224 char **previous, char **current)
226 DBusMessageIter item_iter;
228 dbus_message_iter_init(msg, &item_iter);
230 if (dbus_message_iter_get_arg_type(&item_iter)
231 != DBUS_TYPE_STRING) {
232 ERR("This is bad format dbus\n");
233 return BLUETOOTH_ERROR_INTERNAL;
236 dbus_message_iter_get_basic(&item_iter, name);
238 retv_if(*name == NULL, BLUETOOTH_ERROR_INTERNAL);
240 dbus_message_iter_next(&item_iter);
242 if (dbus_message_iter_get_arg_type(&item_iter)
243 != DBUS_TYPE_STRING) {
244 ERR("This is bad format dbus\n");
245 return BLUETOOTH_ERROR_INTERNAL;
248 dbus_message_iter_get_basic(&item_iter, previous);
250 retv_if(*previous == NULL, BLUETOOTH_ERROR_INTERNAL);
252 dbus_message_iter_next(&item_iter);
254 if (dbus_message_iter_get_arg_type(&item_iter)
255 != DBUS_TYPE_STRING) {
256 ERR("This is bad format dbus\n");
257 return BLUETOOTH_ERROR_INTERNAL;
260 dbus_message_iter_get_basic(&item_iter, current);
262 retv_if(*current == NULL, BLUETOOTH_ERROR_INTERNAL);
264 return BLUETOOTH_ERROR_NONE;
267 static DBusHandlerResult __event_filter(DBusConnection *sys_conn,
268 DBusMessage *msg, void *data)
272 struct bt_appdata *ad = app_state;
273 const char *path = dbus_message_get_path(msg);
277 bt_share_cynara_creds sender_creds;
280 if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL)
281 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
283 if (path == NULL || strcmp(path, "/") == 0)
284 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
286 member = (char *)dbus_message_get_member(msg);
287 DBG("member (%s)\n", member);
289 if (dbus_message_is_signal(msg, BT_SYSPOPUP_INTERFACE, BT_SYSPOPUP_METHOD_RESPONSE)) {
291 dbus_message_get_args(msg, NULL,
292 DBUS_TYPE_INT32, &res,
295 } else if (dbus_message_is_signal(msg, BT_UG_IPC_INTERFACE, BT_UG_IPC_METHOD_SEND)) {
296 opc_transfer_info_t *node;
299 sender = dbus_message_get_sender(msg);
300 ret = _bt_share_cynara_get_creds(sys_conn, sender, &sender_creds);
302 ERR("acquiring cynara creds failed\n");
303 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
306 if (_bt_share_cynara_check(&sender_creds, BT_SHARE_PRIVILEGE) != BT_SHARE_FAIL) {
307 ERR("Cynara denied file send\n");
308 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
311 node = __add_transfer_info(msg);
313 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
315 ret = _request_file_send(node);
316 if (ret == BLUETOOTH_ERROR_IN_PROGRESS) {
317 DBG("Aleady OPC progressing. Once completed previous job, will be started\n");
318 } else if ( ret != BLUETOOTH_ERROR_NONE) {
319 _bt_create_warning_popup(BLUETOOTH_ERROR_INTERNAL, BT_STR_UNABLE_TO_SEND);
320 g_slist_free_full(bt_transfer_list,
321 (GDestroyNotify)_free_transfer_info);
322 bt_transfer_list = NULL;
324 } else if (dbus_message_is_signal(msg, BT_SHARE_UI_INTERFACE, BT_SHARE_UI_SIGNAL_OPPABORT)) {
325 const char *transfer_type = NULL;
328 if (!dbus_message_get_args(msg, NULL,
329 DBUS_TYPE_STRING, &transfer_type,
330 DBUS_TYPE_INT32, ¬i_id,
331 DBUS_TYPE_INVALID)) {
332 ERR("OPP abort handling failed");
333 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
335 ad->opp_transfer_abort = TRUE; /* Transfer aborted by user*/
336 INFO("transfer_type = %s", transfer_type);
337 if (!g_strcmp0(transfer_type, NOTI_TR_TYPE_OUT)) {
338 bluetooth_opc_cancel_push();
340 ret = _bt_delete_notification(ad->opc_noti);
341 if (ret == NOTIFICATION_ERROR_NONE) {
347 bluetooth_obex_server_cancel_transfer(noti_id);
349 } else if (dbus_message_is_signal(msg, BT_SHARE_UI_INTERFACE,
350 BT_SHARE_UI_SIGNAL_SEND_FILE)) {
351 opc_transfer_info_t *node;
354 sender = dbus_message_get_sender(msg);
355 ret = _bt_share_cynara_get_creds(sys_conn, sender, &sender_creds);
357 ERR("acquiring cynara creds failed\n");
358 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
361 if (_bt_share_cynara_check(&sender_creds, BT_SHARE_PRIVILEGE) != BT_SHARE_FAIL) {
362 ERR("Cynara denied file send\n");
363 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
366 node = __add_transfer_info(msg);
368 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
370 ret = _request_file_send(node);
371 if (ret == BLUETOOTH_ERROR_IN_PROGRESS) {
372 DBG("Aleady OPC progressing. Once completed previous job, will be started\n");
373 } else if ( ret != BLUETOOTH_ERROR_NONE) {
374 _bt_create_warning_popup(BLUETOOTH_ERROR_INTERNAL, BT_STR_UNABLE_TO_SEND);
375 g_slist_free_full(bt_transfer_list,
376 (GDestroyNotify)_free_transfer_info);
377 bt_transfer_list = NULL;
379 } else if (dbus_message_is_signal(msg, BT_SHARE_UI_INTERFACE,
380 BT_SHARE_UI_SIGNAL_INFO_UPDATE)) {
383 dbus_message_get_args(msg, NULL,
384 DBUS_TYPE_INT32, &tr_uid,
385 DBUS_TYPE_INT32, &tr_type,
388 DBG("tr_uid = %d, tr_type = %d \n", tr_uid, tr_type);
389 __bt_share_update_tr_info(tr_uid, tr_type);
390 } else if (dbus_message_is_signal(msg, BT_SHARE_FRWK_INTERFACE,
391 BT_SHARE_FRWK_SIGNAL_DEINIT)) {
392 /* Deinitialize the obex server */
393 if (bluetooth_obex_server_deinit() == BLUETOOTH_ERROR_NONE) {
394 DBG("Obex Server deinit");
396 } else if (strcasecmp(member, "NameOwnerChanged") == 0) {
398 char *previous = NULL;
399 char *current = NULL;
401 if (__bt_get_owner_info(msg, &name, &previous, ¤t)) {
402 ERR("Fail to get the owner info");
403 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
406 if (*current != '\0')
407 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
409 if (strcasecmp(name, "org.bluez") == 0) {
410 INFO("Bluetoothd is terminated");
411 _bt_terminate_bluetooth_share();
414 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
416 return DBUS_HANDLER_RESULT_HANDLED;
419 gboolean _bt_init_dbus_signal(void)
422 DBusError dbus_error;
424 dbus_error_init(&dbus_error);
426 dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error);
428 if (!dbus_connection) {
429 ERR(" DBUS get failed");
430 if (dbus_error_is_set(&dbus_error)) {
431 ERR("D-Bus Error: %s\n", dbus_error.message);
432 dbus_error_free(&dbus_error);
437 /* Add the filter for network client functions */
438 dbus_connection_add_filter(dbus_connection, __event_filter, NULL, NULL);
439 dbus_bus_add_match(dbus_connection,
440 "type=signal,interface=" BT_BLUEZ_INTERFACE
441 ",member=NameOwnerChanged", &dbus_error);
442 dbus_bus_add_match(dbus_connection,
443 "type=signal,interface=" BT_SYSPOPUP_INTERFACE
444 ",member=Response", &dbus_error);
445 dbus_bus_add_match(dbus_connection,
446 "type=signal,interface=" BT_UG_IPC_INTERFACE
447 ",member=Send", &dbus_error);
448 dbus_bus_add_match(dbus_connection,
449 "type=signal,interface=" BT_SHARE_UI_INTERFACE
450 ",member=opp_abort", &dbus_error);
451 dbus_bus_add_match(dbus_connection,
452 "type=signal,interface=" BT_SHARE_UI_INTERFACE
453 ",member=send_file", &dbus_error);
454 dbus_bus_add_match(dbus_connection,
455 "type=signal,interface=" BT_SHARE_UI_INTERFACE
456 ",member=info_update", &dbus_error);
457 dbus_bus_add_match(dbus_connection,
458 "type=signal,interface=" BT_SHARE_FRWK_INTERFACE
459 ",member=deinit", &dbus_error);
460 if (dbus_error_is_set(&dbus_error)) {
461 ERR("Fail to add dbus filter signal");
462 dbus_error_free(&dbus_error);
469 void _bt_send_message_to_ui(int transfer_id, char *name, int percentage, gboolean completed, int error_type)
471 DBusMessage *msg = NULL;
473 ret_if(dbus_connection == NULL);
474 ret_if(name == NULL);
476 msg = dbus_message_new_signal(BT_SHARE_ENG_OBJECT,
477 BT_SHARE_ENG_INTERFACE,
478 BT_SHARE_ENG_SIGNAL_PROGRESS);
480 ERR("Unable to allocate memory\n");
483 if (!dbus_message_append_args(msg,
484 DBUS_TYPE_INT32, &transfer_id,
485 DBUS_TYPE_STRING, &name,
486 DBUS_TYPE_INT32, &percentage,
487 DBUS_TYPE_BOOLEAN, &completed,
488 DBUS_TYPE_INT32, &error_type,
489 DBUS_TYPE_INVALID)) {
490 ERR("Event sending failed\n");
491 dbus_message_unref(msg);
494 DBG("Dbus send message append request is done.\n");
496 dbus_message_set_destination(msg, BT_SHARE_UI_INTERFACE);
497 dbus_connection_send(dbus_connection, msg, NULL);
498 dbus_message_unref(msg);
504 void _bt_create_warning_popup(int error_type, char *msg)
506 /* If bluetooth-share-ui process is not running */
507 /* Then create the process and terminate it after popup shown */
508 if (aul_app_is_running(UI_PACKAGE) == 0) {
509 DBG("Creating new process for Warning Popup");
510 char str[BT_TEXT_LEN_MAX] = { 0, };
513 DBG("error_type: %d",error_type);
514 switch (error_type) {
515 case BLUETOOTH_ERROR_SERVICE_NOT_FOUND:
516 case BLUETOOTH_ERROR_NOT_CONNECTED:
517 case BLUETOOTH_ERROR_ACCESS_DENIED:
518 case BLUETOOTH_ERROR_OUT_OF_MEMORY:
519 case BLUETOOTH_ERROR_INTERNAL:
520 case BLUETOOTH_ERROR_CANCEL:
521 snprintf(str, BT_TEXT_LEN_MAX, "%s",
531 bundle_add(b, "launch-type", "warning_popup");
532 bundle_add(b, "message", str);
534 aul_launch_app(UI_PACKAGE, b);
541 void _bt_update_transfer_list_view(const char *table)
543 DBusMessage *msg = NULL;
544 ret_if(dbus_connection == NULL);
546 msg = dbus_message_new_signal(BT_SHARE_ENG_OBJECT,
547 BT_SHARE_ENG_INTERFACE,
548 BT_SHARE_ENG_SIGNAL_UPDATE_VIEW);
550 ERR("Unable to allocate memory\n");
554 if (!dbus_message_append_args(msg,
555 DBUS_TYPE_STRING, &table,
556 DBUS_TYPE_INVALID)) {
557 DBG("Event sending failed\n");
558 dbus_message_unref(msg);
562 dbus_message_set_destination(msg, BT_SHARE_UI_INTERFACE);
563 dbus_connection_send(dbus_connection, msg, NULL);
564 dbus_message_unref(msg);
567 static time_t __bt_get_current_timedata(void)
574 static char *__bt_conv_addr_type_to_addr_string(char *addr)
576 char address[BT_ADDR_STR_LEN_MAX] = {0,};
577 retv_if(addr == NULL, NULL);
579 snprintf(address, BT_ADDR_STR_LEN_MAX,
580 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
581 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
583 return g_strdup(address);
586 static void __bt_create_send_data(opc_transfer_info_t *node)
588 DBG("__bt_create_send_data \n");
589 ret_if(node == NULL);
590 struct bt_appdata *ad = app_state;
597 DBG("Name [%s]\n", node->name);
599 db = bt_share_open_db();
603 session_id = bt_share_get_last_session_id(db, BT_DB_OUTBOUND);
604 DBG("Last session id = %d\n", session_id);
605 for (count = 0; count < node->file_cnt; count++) {
607 tmp = g_malloc0(sizeof(bt_tr_data_t));
611 tmp->tr_status = BT_TR_ONGOING;
612 tmp->sid = session_id + 1;
613 tmp->file_path = g_strdup(node->file_path[count]);
614 DBG("tmp->file_path : %s", tmp->file_path);
616 tmp->content = g_strdup(node->content[count]);
617 tmp->dev_name = g_strdup(node->name);
618 tmp->type = g_strdup(node->type);
619 tmp->timestamp = __bt_get_current_timedata();
620 tmp->addr = __bt_conv_addr_type_to_addr_string(node->addr);
621 tmp->size = node->size[count];
622 bt_share_add_tr_data(db, BT_DB_OUTBOUND, tmp);
623 __bt_tr_data_free(tmp);
627 if (ad->tr_send_list) {
628 bt_share_release_tr_data_list(ad->tr_send_list);
629 ad->tr_send_list = NULL;
632 ad->tr_send_list = bt_share_get_tr_data_list_by_status(db,
633 BT_DB_OUTBOUND, BT_TR_ONGOING);
634 bt_share_close_db(db);
636 if (ad->tr_send_list == NULL)
639 ad->tr_next_data = ad->tr_send_list;
644 gboolean _bt_update_sent_data_status(int uid, bt_app_tr_status_t status)
646 DBG("_bt_update_sent_data_status \n");
648 DBG("uid = %d \n", uid);
652 db = bt_share_open_db();
656 tmp = g_malloc0(sizeof(bt_tr_data_t));
660 tmp->tr_status = status;
661 tmp->timestamp = __bt_get_current_timedata();
662 bt_share_update_tr_data(db, BT_DB_OUTBOUND, uid, tmp);
663 bt_share_close_db(db);
664 __bt_tr_data_free(tmp);
669 gboolean _bt_add_recv_transfer_status_data(char *device_name,
670 char *filepath, char *type,
671 unsigned int size, int status)
673 if (device_name == NULL || filepath == NULL)
679 DBG("Name [%s]\n", device_name);
681 db = bt_share_open_db();
685 tmp = g_malloc0(sizeof(bt_tr_data_t));
689 tmp->tr_status = status;
690 tmp->file_path = g_strdup(filepath);
691 tmp->dev_name = g_strdup(device_name);
692 tmp->timestamp = __bt_get_current_timedata();
693 tmp->type = g_strdup(type);
695 bt_share_add_tr_data(db, BT_DB_INBOUND, tmp);
696 bt_share_close_db(db);
697 __bt_tr_data_free(tmp);
702 static void __bt_share_update_tr_info(int tr_uid, int tr_type)
704 DBG("__bt_share_update_tr_info tr_uid = %d \n", tr_uid);
706 struct bt_appdata *ad = app_state;
707 char str[NOTIFICATION_TEXT_LEN_MAX] = { 0 };
708 bt_tr_data_t *info = NULL;
711 db = bt_share_open_db();
715 if (tr_type == BT_TR_OUTBOUND) {
717 /* Click the "clear list" button in bluetooth-share-ui */
718 /* Delete all outbound db / notification info */
719 _bt_delete_notification(ad->send_noti);
720 ad->send_noti = NULL;
721 ad->send_data.tr_success = 0;
722 ad->send_data.tr_fail = 0;
723 bt_share_remove_tr_data_by_notification(db, BT_DB_OUTBOUND);
724 bt_share_close_db(db);
726 /* Delete selected outbound db / notification info */
728 info = bt_share_get_tr_data(db, BT_DB_OUTBOUND, tr_uid);
730 status = info->tr_status;
734 bt_share_remove_tr_data_by_id(db, BT_DB_OUTBOUND, tr_uid);
735 bt_share_close_db(db);
737 if (status == BT_TR_SUCCESS && ad->send_data.tr_success > 0)
738 ad->send_data.tr_success--;
739 else if (status == BT_TR_FAIL && ad->send_data.tr_fail > 0)
740 ad->send_data.tr_fail--;
744 if ((ad->send_data.tr_success + ad->send_data.tr_fail) != 0) {
745 snprintf(str, sizeof(str), "%s %d %d", BT_TR_STATUS,
746 ad->send_data.tr_success, ad->send_data.tr_fail);
748 _bt_update_notification(ad, ad->send_noti,
751 _bt_delete_notification(ad->send_noti);
754 } else if (tr_type == BT_TR_INBOUND) {
756 /* Click the "clear list" button in bluetooth-share-ui */
757 /* Delete all inbound db / notification info */
759 _bt_delete_notification(ad->receive_noti);
760 ad->receive_noti = NULL;
761 ad->recv_data.tr_success = 0;
762 ad->recv_data.tr_fail = 0;
763 bt_share_remove_all_tr_data(db, BT_DB_INBOUND);
764 bt_share_close_db(db);
766 /* Delete selected outbound db / notification info */
768 info = bt_share_get_tr_data(db, BT_DB_INBOUND, tr_uid);
770 status = info->tr_status;
774 bt_share_remove_tr_data_by_id(db, BT_DB_INBOUND, tr_uid);
775 bt_share_close_db(db);
777 if (status == BT_TR_SUCCESS && ad->recv_data.tr_success > 0)
778 ad->recv_data.tr_success--;
779 else if (status == BT_TR_FAIL && ad->recv_data.tr_fail > 0)
780 ad->recv_data.tr_fail--;
784 if ((ad->recv_data.tr_success + ad->recv_data.tr_fail) != 0) {
785 snprintf(str, sizeof(str), "%s %d %d", BT_TR_STATUS,
786 ad->recv_data.tr_success, ad->recv_data.tr_fail);
788 _bt_update_notification(ad, ad->receive_noti,
791 _bt_delete_notification(ad->receive_noti);
795 ERR("Invalid transfer type \n");