From: nazib.ullah Date: Mon, 22 Aug 2016 10:01:30 +0000 (+0600) Subject: [TBT][tizen_3.0_mobile][Gatt Server Module added, Gatt Client Module Updated] X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6967d688f9c80e3d134007c79a612c38bed51895;p=test%2Ftct%2Fnative%2Fbehavior.git [TBT][tizen_3.0_mobile][Gatt Server Module added, Gatt Client Module Updated] Change-Id: I7befabfe60c73dbb0c302fb5bc2daadbc684d608 --- diff --git a/release/binary-armv7l/org.tizen.tbtcoreapp-1.0.0-arm.tpk b/release/binary-armv7l/org.tizen.tbtcoreapp-1.0.0-arm.tpk index 2591347..8134e2b 100644 Binary files a/release/binary-armv7l/org.tizen.tbtcoreapp-1.0.0-arm.tpk and b/release/binary-armv7l/org.tizen.tbtcoreapp-1.0.0-arm.tpk differ diff --git a/release/binary-x86/org.tizen.tbtcoreapp-1.0.0-i386.tpk b/release/binary-x86/org.tizen.tbtcoreapp-1.0.0-i386.tpk index 86a2ef5..cd2dd17 100644 Binary files a/release/binary-x86/org.tizen.tbtcoreapp-1.0.0-i386.tpk and b/release/binary-x86/org.tizen.tbtcoreapp-1.0.0-i386.tpk differ diff --git a/tbtcoreapp/inc/model/tbt-info.h b/tbtcoreapp/inc/model/tbt-info.h index 1c5de2d..e860e3e 100644 --- a/tbtcoreapp/inc/model/tbt-info.h +++ b/tbtcoreapp/inc/model/tbt-info.h @@ -73,6 +73,7 @@ typedef enum { TBT_APP_BT_HDP, TBT_APP_BLE_GATT_CLIENT, + TBT_APP_BLE_GATT_SERVER, TBT_APP_BT_CALLBACK_CREATE_BOND_TEST, TBT_APP_BT_CALLBACK_DESTROY_BOND_TEST, diff --git a/tbtcoreapp/inc/utils/app_module_config.h b/tbtcoreapp/inc/utils/app_module_config.h index bb6518e..02c2365 100644 --- a/tbtcoreapp/inc/utils/app_module_config.h +++ b/tbtcoreapp/inc/utils/app_module_config.h @@ -41,6 +41,8 @@ #define TBT_MODULE_BLE #define TBT_MODULE_BLE_GATT_CLIENT +#define TBT_MODULE_BLE_GATT_SERVER + #define TBT_MODULE_BT_CALLBACK_TEST #define TBT_MODULE_APP_BT_CALLBACK_CREATE_BOND_TEST diff --git a/tbtcoreapp/src/model/tbt-list.c b/tbtcoreapp/src/model/tbt-list.c index f004b54..0e609cc 100644 --- a/tbtcoreapp/src/model/tbt-list.c +++ b/tbtcoreapp/src/model/tbt-list.c @@ -148,17 +148,32 @@ static tbt_info tbtapps[] = #endif #ifdef TBT_MODULE_BLE - //Bluetooth LE Gatt Client - { - .name = "Gatt Client", - .parent = "Bluetooth LE", - .apptype = TBT_APP_BLE_GATT_CLIENT, - .icon_name = "dummy", - .info = "Bluetooth LE Gatt Cleint", - .result = 0, - .required_features_count = 1, - .features_required = {16} - }, + #ifdef TBT_MODULE_BLE_GATT_CLIENT + //Bluetooth LE Gatt Client + { + .name = "Gatt Client", + .parent = "Bluetooth LE", + .apptype = TBT_APP_BLE_GATT_CLIENT, + .icon_name = "dummy", + .info = "Bluetooth LE Gatt Cleint", + .result = 0, + .required_features_count = 1, + .features_required = {16} + }, + #endif + #ifdef TBT_MODULE_BLE_GATT_SERVER + //Bluetooth LE Gatt Server + { + .name = "Gatt Server", + .parent = "Bluetooth LE", + .apptype = TBT_APP_BLE_GATT_SERVER, + .icon_name = "dummy", + .info = "Bluetooth LE Gatt Cleint", + .result = 0, + .required_features_count = 1, + .features_required = {16} + }, + #endif #endif #ifdef TBT_MODULE_BT diff --git a/tbtcoreapp/src/view/tbt-bluetoothle-view.c b/tbtcoreapp/src/view/tbt-bluetoothle-view.c index 1f05243..3ab97ef 100644 --- a/tbtcoreapp/src/view/tbt-bluetoothle-view.c +++ b/tbtcoreapp/src/view/tbt-bluetoothle-view.c @@ -40,17 +40,18 @@ typedef enum { SERVICE_LISTED, -SERVICE_SELECTED, SERVICE_EXPANDED, -CHARACTERISTICS_LISTED, -CHARACTERISTIC_SELECTED, -CHARACTERISTIC_READ, -CHARACTERISTIC_WRITTEN, -CHARACTERISTIC_EXPANDED, -DESCRIPTORS_LISTED, -DESCRIPTORS_SELECTED, -DESCRIPTORS_READ, -DESCRIPTORS_WRITTEN +BATTERY_CHARACTERISTIC_SELECTED, +BATTERY_CHARACTERISTIC_READ, +BATTERY_CHARACTERISTIC_EXPANDED, +BATTERY_DESCRIPTORS_LISTED, +BATTERY_DESCRIPTORS_SELECTED, +BATTERY_DESCRIPTORS_READ, +BATTERY_DESCRIPTORS_WRITTEN, + +LINK_LOSS_CHARACTERISTIC_SELECTED, +LINK_LOSS_CHARACTERISTIC_READ, +LINK_LOSS_CHARACTERISTIC_WRITTEN }ctrl_btn_state_e; @@ -63,6 +64,7 @@ struct _bluetoothle_view Evas_Object *write_btn; Evas_Object *expand_btn; Evas_Object *bluetoothle_btn2; + Evas_Object *disconnect_btn; bt_adapter_state_e adapter_state; bt_adapter_visibility_mode_e visibility_mode; common_view* view; @@ -73,7 +75,7 @@ struct _bluetoothle_view Elm_Object_Item *selected_device_item; GList *devices_list; - GList *log_list; + GList *services_list; bt_gatt_client_h client; bt_gatt_h gatt_handle; bt_gatt_h characterstic_h, service_h, descriptor_h; @@ -83,7 +85,29 @@ struct _bluetoothle_view int n_characteristics; bt_gatt_type_e type; - bool is_int; + + bt_gatt_server_h server_handle; + bt_gatt_h battery_service; + bt_gatt_h battery_characteristic; + bt_gatt_h battery_descriptor; + bt_gatt_h battery_descriptor2; + bt_gatt_h link_loss_service; + bt_gatt_h link_loss_characteristic; + + bt_advertiser_h advertiser; + + bool service_exists; + bool will_back_cb_removed; + + bool is_battery_svc_selected; + bool is_link_loss_svc_selected; + + char* remote_server_address; + + Evas_Object* notify_btn; + char* client_address; + + bool is_bonded; }; @@ -91,6 +115,8 @@ static void _app_destroy_cb(void* this); static void init_bluetooth(void* user_data); static void _adapter_state_changed_cb(int result, bt_adapter_state_e adapter_state, void *user_data); static void discover_bluetooth_le(void* user_data); +static void start_bluetooth_le_server(void* user_data); +static void make_service(void* user_data); static void _bt_adapter_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data); static bool is_new_scanned_device_found(bluetoothle_view *this, bt_adapter_le_device_scan_result_info_s *discovery_info); static gint bluetooth_list_find_func_cb(gconstpointer a, gconstpointer b); @@ -120,6 +146,18 @@ static bool _bt_gatt_foreach_descriptors_cb(int total, int index, bt_gatt_h gatt static void _bt_gatt_client_characteristic_value_changed_cb(bt_gatt_h characteristic, char *value, int len, void *user_data); static void log_list_free_func_cb(gpointer data); +static void _adapter_device_bond_destroyed_cb(int result, char *remote_address, void *data); +static void _bt_device_bond_created_cb(int result, bt_device_info_s *device_info, void *user_data); +static void _disconnect_button_pressed_cb(void *user_data, Evas_Object *obj, void *event_info); +static void bluetooth_le_advertise(void* user_data); +static void _bt_gatt_server_read_value_requested_cb(const char *remote_address, int request_id, bt_gatt_server_h server, bt_gatt_h gatt_handle, int offset, void *user_data); +static void _bt_gatt_server_characteristic_notification_state_changed_cb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle, void *user_data); +static void _bt_gatt_server_write_value_requested_cb(const char *remote_address, int request_id, bt_gatt_server_h server, bt_gatt_h gatt_handle, int offset, const char *value, int len, void *user_data); +static void _bt_adapter_le_advertising_state_changed_cb(int result, bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e adv_state, void *user_data); +static void services_list_show(bluetoothle_view *this); +static void on_hardware_back_button_pressed(void *user_data, Evas_Object *obj, void *event_info); +static void _notify_button_pressed_cb(void *user_data, Evas_Object *obj, void *event_info); +static void _bt_gatt_server_notification_sent_cb(int result, const char *remote_address, bt_gatt_server_h server, bt_gatt_h characteristic, bool completed, void *user_data); /** * @function bluetoothle_view_add @@ -142,6 +180,18 @@ bluetoothle_view *bluetoothle_view_add(Evas_Object *navi, tbt_info *tbt_info, El this->view = calloc(1, sizeof(common_view)); RETVM_IF(!this->view, NULL, "calloc failed"); + + // + this->server_handle = NULL; + this->battery_service = NULL; + this->battery_characteristic = NULL; + this->battery_descriptor = NULL; + this->link_loss_service = NULL; + this->link_loss_characteristic = NULL; + this->is_bonded = false; + + // + tbt_info->layout_group = "bluetoothle_viewer"; tbt_info->layout_file = get_edje_path("bluetooth_le_viewer.edj"); @@ -151,7 +201,6 @@ bluetoothle_view *bluetoothle_view_add(Evas_Object *navi, tbt_info *tbt_info, El this->scan_info = NULL; this->is_read_completed = true; - this->is_int = true; //Add Label, Button and List this->bluetoothle_label = ui_utils_label_add(this->view->layout, "BLE"); @@ -165,14 +214,37 @@ bluetoothle_view *bluetoothle_view_add(Evas_Object *navi, tbt_info *tbt_info, El Evas_Object *control = add_control_layout(this, this->view->layout); elm_object_part_content_set(this->view->layout, "controlr_part", control); - //Initialize Bluetooth init_bluetooth(this); + if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_CLIENT) + { + eext_object_event_callback_add(this->view->layout, EEXT_CALLBACK_BACK, on_hardware_back_button_pressed, this); + } return this; } +static void on_hardware_back_button_pressed(void *user_data, Evas_Object *obj, void *event_info) +{ + DBG("on_hardware_back_button_pressed"); + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + + DBG("service_exists %d will_back_cb_removed %d", this->service_exists,this->will_back_cb_removed); + + if(this->service_exists) + { + if(this->will_back_cb_removed) + { + eext_object_event_callback_del(this->view->layout, EEXT_CALLBACK_BACK, on_hardware_back_button_pressed); + this->will_back_cb_removed = true; + } + services_list_show(this); + } +} + /** * @function discover_bluetooth_le * @since_tizen 2.3 @@ -182,6 +254,7 @@ bluetoothle_view *bluetoothle_view_add(Evas_Object *navi, tbt_info *tbt_info, El */ static void discover_bluetooth_le(void* user_data) { + DBG("discover_bluetooth_le"); int result; bluetoothle_view *this = NULL; this = (bluetoothle_view*)user_data; @@ -194,7 +267,146 @@ static void discover_bluetooth_le(void* user_data) RETM_IF(result != BT_ERROR_NONE, "bt_adapter_le_start_scan failed --> error: %s", get_bluetooth_error(result)); } +static void start_bluetooth_le_server(void* user_data) +{ + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + + this->server_handle = NULL; + + make_service(this); + +} + + +static void make_service(void* user_data) +{ + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL") + + char *battery_service_uuid = "180f"; // Battery Service + char *battery_char_uuid = "2a19"; // Battery Level + char *battery_desc_uuid = "2902"; // CCCD + char *battery_desc_uuid2 = "2904"; //characteristic format + char battery_char_value[1] = {80}; // 80% + char battery_desc_value[2] = {0, 0}; // Notification & Indication disabled + int battery_permissions = BT_GATT_PERMISSION_READ; + int battery_properties = BT_GATT_PROPERTY_READ | BT_GATT_PROPERTY_NOTIFY; + + char *link_loss_service_uuid = "1803"; /* Link Loss Service */ + char *link_loss_char_uuid = "2a06"; /* Alert Level */ + char link_loss_char_value[1] = {2}; /* high alert */ + int link_loss_permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE; + int link_loss_properties = BT_GATT_PROPERTY_READ | BT_GATT_PROPERTY_WRITE; + + int ret; + if(this->adapter_state == BT_ADAPTER_ENABLED) + { + //create server + ret = bt_gatt_server_initialize(); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_initialize failed --> error: %s", get_bluetooth_error(ret)); + if(this->server_handle == NULL) + { + ret = bt_gatt_server_create(&this->server_handle); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_create failed --> error: %s", get_bluetooth_error(ret)); + } + + + //create battery service + ret = bt_gatt_service_create(battery_service_uuid, BT_GATT_SERVICE_TYPE_PRIMARY, &this->battery_service); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_service_create failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_characteristic_create(battery_char_uuid, battery_permissions, battery_properties, battery_char_value, sizeof(battery_char_value), &this->battery_characteristic); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_characteristic_create failed --> error: %s", get_bluetooth_error(ret)); + + // register callbacks + ret = bt_gatt_server_set_read_value_requested_cb(this->battery_characteristic, _bt_gatt_server_read_value_requested_cb, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_set_read_value_requested_cb failed --> error: %s", get_bluetooth_error(ret)); + ret = bt_gatt_server_set_characteristic_notification_state_change_cb(this->battery_characteristic, _bt_gatt_server_characteristic_notification_state_changed_cb, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_set_characteristic_notification_state_change_cb failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_service_add_characteristic(this->battery_service, this->battery_characteristic); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_service_add_characteristic failed --> error: %s", get_bluetooth_error(ret)); + + battery_permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE; + ret = bt_gatt_descriptor_create(battery_desc_uuid, battery_permissions, battery_desc_value, sizeof(battery_desc_value), &this->battery_descriptor); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_descriptor_create failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_descriptor_create(battery_desc_uuid2, battery_permissions, battery_desc_value, sizeof(battery_desc_value), &this->battery_descriptor2); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_descriptor_create failed --> error: %s", get_bluetooth_error(ret)); + + + ret = bt_gatt_server_set_read_value_requested_cb(this->battery_descriptor2, _bt_gatt_server_read_value_requested_cb, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_set_read_value_requested_cb failed --> error: %s", get_bluetooth_error(ret)); + ret = bt_gatt_server_set_write_value_requested_cb(this->battery_descriptor2, _bt_gatt_server_write_value_requested_cb, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_set_write_value_requested_cb failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_characteristic_add_descriptor(this->battery_characteristic, this->battery_descriptor); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_characteristic_add_descriptor failed --> error: %s", get_bluetooth_error(ret)); + ret = bt_gatt_characteristic_add_descriptor(this->battery_characteristic, this->battery_descriptor2); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_characteristic_add_descriptor failed --> error: %s", get_bluetooth_error(ret)); + + + + //create link loss service + ret = bt_gatt_service_create(link_loss_service_uuid, BT_GATT_SERVICE_TYPE_PRIMARY, &this->link_loss_service); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_service_create failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_characteristic_create(link_loss_char_uuid, link_loss_permissions, link_loss_properties, link_loss_char_value, sizeof(link_loss_char_value), &this->link_loss_characteristic); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_characteristic_create failed --> error: %s", get_bluetooth_error(ret)); + + // register callbacks + ret = bt_gatt_server_set_read_value_requested_cb(this->link_loss_characteristic, _bt_gatt_server_read_value_requested_cb, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_set_read_value_requested_cb failed --> error: %s", get_bluetooth_error(ret)); + ret = bt_gatt_server_set_write_value_requested_cb(this->link_loss_characteristic, _bt_gatt_server_write_value_requested_cb, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_set_write_value_requested_cb failed --> error: %s", get_bluetooth_error(ret)); + ret = bt_gatt_server_set_characteristic_notification_state_change_cb(this->link_loss_characteristic, _bt_gatt_server_characteristic_notification_state_changed_cb, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_set_characteristic_notification_state_change_cb failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_service_add_characteristic(this->link_loss_service, this->link_loss_characteristic); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_service_add_characteristic failed --> error: %s", get_bluetooth_error(ret)); + + + //register services + ret = bt_gatt_server_register_service(this->server_handle, this->battery_service); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_register_service failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_server_register_service(this->server_handle, this->link_loss_service); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_register_service failed --> error: %s", get_bluetooth_error(ret)); + + ret = bt_gatt_server_start(); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_start failed --> error: %s", get_bluetooth_error(ret)); + + bluetooth_le_advertise(this); + } +} + +static void _adapter_device_bond_destroyed_cb(int result, char *remote_address, void *data) +{ + DBG("_adapter_device_bond_destroyed_cb"); + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)data; + this->is_bonded = false; +} + +static void _bt_device_bond_created_cb(int result_recieved, bt_device_info_s *device_info, void *user_data) +{ + DBG("_bt_device_bond_created_cb %d", result_recieved); + + int result; + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + result = bt_gatt_connect(device_info->remote_address, false); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_connect failed --> error: %s", get_bluetooth_error(result)); + elm_object_text_set(this->bluetoothle_label, "gatt connecting..."); + elm_object_disabled_set(this->bluetoothle_btn, EINA_TRUE); + elm_object_disabled_set(this->disconnect_btn, EINA_FALSE); + this->is_bonded = device_info->is_bonded; +} /** * @function register_callback * @since_tizen 2.3 @@ -212,6 +424,12 @@ static void register_callback(void* user_data) result = bt_adapter_set_state_changed_cb(_adapter_state_changed_cb , this); RETM_IF(result != BT_ERROR_NONE, "bt_adapter_set_state_changed_cb Failed"); + result = bt_device_set_bond_created_cb(_bt_device_bond_created_cb, this); + RETM_IF(result != BT_ERROR_NONE, "bt_device_set_bond_created_cb Failed"); + + result = bt_device_set_bond_destroyed_cb(_adapter_device_bond_destroyed_cb, this); + RETM_IF(result != BT_ERROR_NONE, "bt_device_set_bond_destroyed_cb Failed"); + result = bt_gatt_set_connection_state_changed_cb(_bt_gatt_connection_state_changed_cb, this); RETM_IF(result != BT_ERROR_NONE, "bt_gatt_set_connection_state_changed_cb failed --> error: %s", get_bluetooth_error(result)); @@ -331,7 +549,12 @@ static Evas_Object *add_control_layout(bluetoothle_view *this, Evas_Object *pare if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_CLIENT) { this->bluetoothle_btn = ui_utils_push_button_add(this, table, "Discover", _control_button_pressed_cb); - elm_table_pack(table, this->bluetoothle_btn, 0, 0, 3, 1); + elm_table_pack(table, this->bluetoothle_btn, 0, 0, 1, 1); + + this->disconnect_btn = ui_utils_push_button_add(this, table, "Disconnect", _disconnect_button_pressed_cb); + elm_table_pack(table, this->disconnect_btn, 1, 0, 1, 1); + + elm_object_disabled_set(this->disconnect_btn, EINA_TRUE); this->read_btn = ui_utils_push_button_add(this, table, "Read", _read_button_pressed_cb); elm_table_pack(table, this->read_btn, 0, 1, 1, 1); @@ -344,10 +567,50 @@ static Evas_Object *add_control_layout(bluetoothle_view *this, Evas_Object *pare set_control_btn_state(SERVICE_LISTED, this); } + else if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_SERVER) + { + //Gatt Server control layout + this->bluetoothle_btn = ui_utils_push_button_add(this, table, "Start Server", _control_button_pressed_cb); + elm_table_pack(table, this->bluetoothle_btn, 0, 0, 3, 1); + + this->notify_btn = ui_utils_push_button_add(this, table, "Notify", _notify_button_pressed_cb); + elm_table_pack(table, this->notify_btn, 0, 1, 3, 1); + + } return table; } +static void _notify_button_pressed_cb(void *user_data, Evas_Object *obj, void *event_info) +{ + DBG("_notify_button_pressed_cb"); + RETM_IF(NULL == user_data, "data is NULL"); + RETM_IF(NULL == obj, "obj is NULL"); + + + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + char char_value[1] = {1 + (rand()%100)}; + + int ret; + + ret = bt_gatt_set_value(this->battery_characteristic, char_value, 1); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_set_value failed --> error: %s", get_bluetooth_error(ret)); + DBG("Value[%d], returns %s\n", char_value[0], get_bluetooth_error(ret)); + + /* notify only client remote_addr */ + ret = bt_gatt_server_notify_characteristic_changed_value(this->battery_characteristic, + _bt_gatt_server_notification_sent_cb, + this->client_address, this); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_server_notify_characteristic_changed_value failed --> error: %s", get_bluetooth_error(ret)); + +} + +static void _bt_gatt_server_notification_sent_cb(int result, const char *remote_address, bt_gatt_server_h server, bt_gatt_h characteristic, bool completed, void *user_data) +{ + DBG("_bt_gatt_server_notification_sent_cb"); +} /** * @function _control_button_pressed_cb @@ -367,10 +630,35 @@ static void _control_button_pressed_cb(void *user_data, Evas_Object *obj, void * bluetoothle_view *this = NULL; this = (bluetoothle_view*)user_data; RETM_IF(NULL == this, "view is NULL"); - //Discover Bluetooth LE Devices - discover_bluetooth_le(this); + if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_CLIENT) + { + //Discover Bluetooth LE Devices + discover_bluetooth_le(this); + } + else if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_SERVER) + { + //Start Server + start_bluetooth_le_server(this); + } + } +static void _disconnect_button_pressed_cb(void *user_data, Evas_Object *obj, void *event_info) +{ + DBG("_disconnect_button_pressed_cb"); + + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + + int result; + + DBG("remote_server_address %s", this->remote_server_address); + result = bt_gatt_disconnect(this->remote_server_address); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_disconnect failed --> error: %s", get_bluetooth_error(result)); + + +} /** * @function _read_button_pressed_cb @@ -395,53 +683,23 @@ static void _read_button_pressed_cb(void *user_data, Evas_Object *obj, void *eve if(type == BT_GATT_TYPE_SERVICE) { - + DBG("reading services..."); } else if(type == BT_GATT_TYPE_CHARACTERISTIC) { + DBG("reading characteristics..."); result = bt_gatt_client_read_value(this->gatt_handle, _bt_gatt_client_read_request_completed_cb, this); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_client_set_characteristic_value_changed_cb error: %s", get_bluetooth_error(result)); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_client_read_value error: %s", get_bluetooth_error(result)); } else if(type == BT_GATT_TYPE_DESCRIPTOR) { - int value; - int result; - char* str; - float f_val; - if(this->descriptor_h == NULL){DBG("THIS IS NULL");} - if(this->is_int) - { - result = bt_gatt_get_int_value(this->descriptor_h, BT_DATA_TYPE_UINT8, 0, &value); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_get_int_value failed --> error: %s", get_bluetooth_error(result)); + DBG("reading descriptor..."); - str = format_string("Descriptor value %d", value); - elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); - SAFE_DELETE(str); - - elm_list_go(this->bluetoothle_list); - evas_object_show(this->bluetoothle_list); - - set_control_btn_state(DESCRIPTORS_SELECTED, this); - elm_object_text_set(this->read_btn, "Read float"); - elm_object_text_set(this->write_btn, "Write float"); - this->is_int = false; - } - else - { - result = bt_gatt_get_float_value(this->descriptor_h, BT_DATA_TYPE_FLOAT, 0, &f_val); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_get_float_value error: %s", get_bluetooth_error(result)); - str = format_string("Descriptor float value %f", f_val); - elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); - SAFE_DELETE(str); - - elm_list_go(this->bluetoothle_list); - evas_object_show(this->bluetoothle_list); - - set_control_btn_state(DESCRIPTORS_READ, this); - } + result = bt_gatt_client_read_value(this->gatt_handle, _bt_gatt_client_read_request_completed_cb, this); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_client_read_value error: %s", get_bluetooth_error(result)); } @@ -475,7 +733,8 @@ static void _write_button_pressed_cb(void *user_data, Evas_Object *obj, void *ev } else if(type == BT_GATT_TYPE_CHARACTERISTIC) { - result = bt_gatt_set_value(this->gatt_handle, "Nazib", 5); + DBG("writing characteristics"); + result = bt_gatt_set_value(this->gatt_handle, "Hello", 5); RETM_IF(result != BT_ERROR_NONE, "bt_gatt_set_value error: %s", get_bluetooth_error(result)); result = bt_gatt_client_write_value(this->gatt_handle, _bt_gatt_client_write_request_completed_cb, this); @@ -484,19 +743,19 @@ static void _write_button_pressed_cb(void *user_data, Evas_Object *obj, void *ev } else if(type == BT_GATT_TYPE_DESCRIPTOR) { - if(this->is_int) - { - result = bt_gatt_set_int_value(this->descriptor_h, BT_DATA_TYPE_UINT8, 25, 0); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_set_int_value error: %s", get_bluetooth_error(result)); + DBG("writing descriptor"); + DBG("writing int"); + result = bt_gatt_set_int_value(this->gatt_handle, BT_DATA_TYPE_UINT8, 25, 0); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_set_int_value error: %s", get_bluetooth_error(result)); - } - else - { - result = bt_gatt_set_float_value(this->descriptor_h, BT_DATA_TYPE_FLOAT, 152, 2, 0); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_set_int_value error: %s", get_bluetooth_error(result)); - } + DBG("writing float"); + result = bt_gatt_set_float_value(this->gatt_handle, BT_DATA_TYPE_FLOAT, 152, 2, 0); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_set_int_value error: %s", get_bluetooth_error(result)); + + result = bt_gatt_client_write_value(this->gatt_handle, _bt_gatt_client_write_request_completed_cb, this); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_client_write_value error: %s", get_bluetooth_error(result)); - set_control_btn_state(DESCRIPTORS_WRITTEN, this); + set_control_btn_state(BATTERY_DESCRIPTORS_WRITTEN, this); } } @@ -539,7 +798,7 @@ static void _expand_button_pressed_cb(void *user_data, Evas_Object *obj, void *e result = bt_gatt_characteristic_foreach_descriptors(this->characterstic_h, _bt_gatt_foreach_descriptors_cb, this); RETM_IF(result != BT_ERROR_NONE,"bt_gatt_characteristic_foreach_descriptors error: %s", get_bluetooth_error(result)); - set_control_btn_state(CHARACTERISTIC_EXPANDED, this); + set_control_btn_state(BATTERY_CHARACTERISTIC_EXPANDED, this); } else if(type == BT_GATT_TYPE_DESCRIPTOR) { @@ -560,7 +819,6 @@ static void set_control_btn_state(ctrl_btn_state_e state, void* user_data) RETM_IF(NULL == user_data, "data is NULL"); bluetoothle_view *this = NULL; this = (bluetoothle_view*)user_data; - RETM_IF(NULL == this, "view is NULL"); switch(state) @@ -572,6 +830,7 @@ switch(state) elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } + case SERVICE_EXPANDED: { elm_object_text_set(this->bluetoothle_label, "Characteristics.."); @@ -580,78 +839,83 @@ switch(state) elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case SERVICE_SELECTED: + + + case LINK_LOSS_CHARACTERISTIC_SELECTED: { - elm_object_text_set(this->bluetoothle_label, "Services.."); - elm_object_disabled_set(this->read_btn, EINA_TRUE); - elm_object_disabled_set(this->write_btn, EINA_TRUE); - elm_object_disabled_set(this->expand_btn, EINA_FALSE); - break; - } - case CHARACTERISTICS_LISTED: - { elm_object_text_set(this->bluetoothle_label, "Characteristics.."); - elm_object_disabled_set(this->read_btn, EINA_TRUE); + elm_object_disabled_set(this->read_btn, EINA_FALSE); elm_object_disabled_set(this->write_btn, EINA_TRUE); elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case CHARACTERISTIC_SELECTED: + case LINK_LOSS_CHARACTERISTIC_READ: { - elm_object_text_set(this->bluetoothle_label, "Characteristics.."); + elm_object_text_set(this->bluetoothle_label, "Read Successfully"); elm_object_disabled_set(this->read_btn, EINA_TRUE); elm_object_disabled_set(this->write_btn, EINA_FALSE); - elm_object_disabled_set(this->expand_btn, EINA_FALSE); + elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case CHARACTERISTIC_READ: - { - elm_object_text_set(this->bluetoothle_label, "Read Successfully"); + case LINK_LOSS_CHARACTERISTIC_WRITTEN: + { elm_object_text_set(this->bluetoothle_label, "Written Successfully"); elm_object_disabled_set(this->read_btn, EINA_TRUE); elm_object_disabled_set(this->write_btn, EINA_TRUE); - elm_object_disabled_set(this->expand_btn, EINA_FALSE); + elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case CHARACTERISTIC_WRITTEN: - { elm_object_text_set(this->bluetoothle_label, "Written Successfully"); + + case BATTERY_CHARACTERISTIC_SELECTED: + { elm_object_disabled_set(this->read_btn, EINA_FALSE); elm_object_disabled_set(this->write_btn, EINA_TRUE); + elm_object_disabled_set(this->expand_btn, EINA_TRUE); + break; + } + + case BATTERY_CHARACTERISTIC_READ: + { + elm_object_text_set(this->bluetoothle_label, "Read Successfully"); + elm_object_disabled_set(this->read_btn, EINA_TRUE); + elm_object_disabled_set(this->write_btn, EINA_TRUE); elm_object_disabled_set(this->expand_btn, EINA_FALSE); break; } - case CHARACTERISTIC_EXPANDED: + + + case BATTERY_CHARACTERISTIC_EXPANDED: { elm_object_text_set(this->bluetoothle_label, "Descriptors.."); elm_object_disabled_set(this->read_btn, EINA_TRUE); elm_object_disabled_set(this->write_btn, EINA_TRUE); elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case DESCRIPTORS_LISTED: + case BATTERY_DESCRIPTORS_LISTED: { elm_object_text_set(this->bluetoothle_label, "Descriptors.."); elm_object_disabled_set(this->read_btn, EINA_TRUE); elm_object_disabled_set(this->write_btn, EINA_TRUE); elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case DESCRIPTORS_SELECTED: + case BATTERY_DESCRIPTORS_SELECTED: { elm_object_text_set(this->bluetoothle_label, "Descriptors.."); - elm_object_disabled_set(this->read_btn, EINA_TRUE); - elm_object_disabled_set(this->write_btn, EINA_FALSE); + elm_object_disabled_set(this->read_btn, EINA_FALSE); + elm_object_disabled_set(this->write_btn, EINA_TRUE); elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case DESCRIPTORS_READ: + case BATTERY_DESCRIPTORS_READ: { elm_object_text_set(this->bluetoothle_label, "Read Successfully"); elm_object_disabled_set(this->read_btn, EINA_TRUE); - elm_object_disabled_set(this->write_btn, EINA_TRUE); + elm_object_disabled_set(this->write_btn, EINA_FALSE); elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; } - case DESCRIPTORS_WRITTEN: + case BATTERY_DESCRIPTORS_WRITTEN: { elm_object_text_set(this->bluetoothle_label, "Written Successfully"); - elm_object_disabled_set(this->read_btn, EINA_FALSE); + elm_object_disabled_set(this->read_btn, EINA_TRUE); elm_object_disabled_set(this->write_btn, EINA_TRUE); elm_object_disabled_set(this->expand_btn, EINA_TRUE); break; @@ -785,25 +1049,12 @@ static bool _bt_gatt_foreach_services_cb(int total, int index, bt_gatt_h gatt_ha RETVM_IF(NULL == gatt_handle,false, "gatt_handle is NULL"); this->gatt_handle = gatt_handle; - - g_list_free_full(this->log_list, log_list_free_func_cb); - this->log_list = NULL; - int result; - - result = bt_gatt_service_get_client(gatt_handle, &this->service_h); - RETVM_IF(result != BT_ERROR_NONE,false, "bt_gatt_service_get_client error: %s", get_bluetooth_error(result)); - char* uuid; result = bt_gatt_get_uuid(gatt_handle, &uuid); RETVM_IF(result != BT_ERROR_NONE,false, "bt_gatt_get_uuid error: %s", get_bluetooth_error(result)); DBG("uuid: %s", uuid); - - char* str; - str = format_string("Service UUID: %s",uuid); - elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, _sevice_selected_cb, gatt_handle); - SAFE_DELETE(str); - + this->services_list = g_list_append(this->services_list, (gpointer) gatt_handle); return true; } @@ -859,7 +1110,6 @@ static bool _bt_gatt_foreach_characterstics_cb(int total, int index, bt_gatt_h g char* str; int result; RETVM_IF(NULL == gatt_handle,false, "gatt_handle is NULL"); - this->gatt_handle = gatt_handle; bt_gatt_write_type_e write_type; result = bt_gatt_characteristic_get_write_type(gatt_handle, &write_type); @@ -871,7 +1121,6 @@ static bool _bt_gatt_foreach_characterstics_cb(int total, int index, bt_gatt_h g bt_gatt_h service; result = bt_gatt_characteristic_get_service(gatt_handle, &service); RETVM_IF(result != BT_ERROR_NONE,false, "bt_gatt_characteristic_get_service error: %s", get_bluetooth_error(result)); - this->service_h = service; this->n_characteristics = total; this->all_characteristics[index] = gatt_handle; @@ -885,19 +1134,11 @@ static bool _bt_gatt_foreach_characterstics_cb(int total, int index, bt_gatt_h g elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, _characteristic_selected_cb, uuid); SAFE_DELETE(str); - result = bt_gatt_client_set_characteristic_value_changed_cb(gatt_handle, _bt_gatt_client_characteristic_value_changed_cb,this); - RETVM_IF(result != BT_ERROR_NONE,false, "bt_gatt_client_set_characteristic_value_changed_cb error: %s", get_bluetooth_error(result)); - this->characterstic_h = gatt_handle; - - - char* service_uuid; result = bt_gatt_get_uuid(gatt_handle, &service_uuid); RETVM_IF(result != BT_ERROR_NONE,false, "bt_gatt_get_uuid error: %s", get_bluetooth_error(result)); DBG("characteristic %d service_uuid: %s",index, service_uuid); - DBG("Total: %d index: %d", total, index); - return true; } @@ -916,18 +1157,15 @@ static void _bt_gatt_client_characteristic_value_changed_cb(bt_gatt_h characteri bluetoothle_view *this = NULL; this = (bluetoothle_view*)user_data; RETM_IF(NULL == this, "view is NULL"); - DBG("value: %s, len %d", value, len); - char* str; - str = format_string("characteristics value changed"); elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); SAFE_DELETE(str); str = format_string("value %s length %d", value, len); elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); SAFE_DELETE(str); - + elm_list_go(this->bluetoothle_list); } @@ -974,7 +1212,6 @@ static bool _bt_gatt_foreach_descriptors_cb(int total, int index, bt_gatt_h gatt elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, _descriptor_selected_cb, descriptor_uuid); SAFE_DELETE(str); SAFE_DELETE(characteristic_uuid); - //SAFE_DELETE(descriptor_uuid); return true; } @@ -994,7 +1231,7 @@ static void _bt_gatt_client_write_request_completed_cb(int result, bt_gatt_h req this = (bluetoothle_view*)user_data; RETM_IF(NULL == this,"view is NULL"); - set_control_btn_state(CHARACTERISTIC_WRITTEN, this); + set_control_btn_state(LINK_LOSS_CHARACTERISTIC_WRITTEN, this); } @@ -1008,7 +1245,6 @@ static void _bt_gatt_client_write_request_completed_cb(int result, bt_gatt_h req static void _bt_gatt_client_read_request_completed_cb(int result, bt_gatt_h request_handle, void *user_data) { - DBG("_bt_gatt_client_read_request_completed_cb"); RETM_IF(NULL == user_data, "data is NULL"); bluetoothle_view *this = NULL; @@ -1017,17 +1253,49 @@ static void _bt_gatt_client_read_request_completed_cb(int result, bt_gatt_h requ this->is_read_completed = true; char* value; int value_length; + RETM_IF(NULL == request_handle,"request_handle is NULL"); result = bt_gatt_get_value(request_handle, &value, &value_length); RETM_IF(result != BT_ERROR_NONE, "bt_gatt_get_value failed --> error: %s", get_bluetooth_error(result)); - DBG("value: %s, value_length: %d", value, value_length); + + for(int i=0; ibluetoothle_list, str, NULL, NULL, NULL, NULL); SAFE_DELETE(str); + elm_list_go(this->bluetoothle_list); + evas_object_show(this->bluetoothle_list); + DBG("read completed"); - set_control_btn_state(CHARACTERISTIC_READ, this); + + bt_gatt_type_e type; + bt_gatt_get_type(this->gatt_handle, &type); + + if(this->is_battery_svc_selected) + { + if(type == BT_GATT_TYPE_CHARACTERISTIC) + { + set_control_btn_state(BATTERY_CHARACTERISTIC_READ, this); + } + else if(type == BT_GATT_TYPE_DESCRIPTOR) + { + set_control_btn_state(BATTERY_DESCRIPTORS_READ, this); + } + } + else if(this->is_link_loss_svc_selected) + { + set_control_btn_state(LINK_LOSS_CHARACTERISTIC_READ, this); + } } @@ -1104,6 +1372,65 @@ static void discovered_devices_list_show(bluetoothle_view *this) } +static void services_list_show(bluetoothle_view *this) +{ + DBG("services_list_show"); + + RETM_IF(NULL == this, "view is NULL"); + this->will_back_cb_removed = true; + elm_list_clear(this->bluetoothle_list); + + GList *l; + bt_gatt_h service_handle; + + int count = 0; + + this->is_battery_svc_selected = false; + this->is_link_loss_svc_selected = false; + + for(l = this->services_list; l != NULL; l = l->next) + { + count++; + service_handle = (bt_gatt_h)l->data; + + if(NULL != service_handle) + { + char* svc_uuid; + char* str; + + bt_gatt_get_uuid(service_handle, &svc_uuid); + + str = format_string("Service UUID: %s",svc_uuid); + + if(!strcmp(svc_uuid, "0000180f-0000-1000-8000-00805f9b34fb")) + { + str = format_string("Battery Service"); + } + else if(!strcmp(svc_uuid, "00001803-0000-1000-8000-00805f9b34fb")) + { + str = format_string("Link Loss Service"); + } + + + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, _sevice_selected_cb, service_handle); + SAFE_DELETE(str); + } + } + + if(count > 0) + { + DBG("Count : %d", count); + this->service_exists = true; + } + + elm_list_go(this->bluetoothle_list); + evas_object_show(this->bluetoothle_list); + + set_control_btn_state(SERVICE_LISTED, this); +} + + + /** * @function _device_item_selected_cb * @since_tizen 2.3 @@ -1137,11 +1464,11 @@ static void _device_item_selected_cb(void *data, Evas_Object *obj, void *event_i result = bt_adapter_le_stop_scan(); RETM_IF(result != BT_ERROR_NONE, "bt_adapter_le_stop_scan fail > Error = %d", result); - result = bt_gatt_connect(device_info->remote_address, false); - DBG("bt_gatt_connect %s", get_bluetooth_error(result)); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_connect failed --> error: %s", get_bluetooth_error(result)); - elm_object_text_set(this->bluetoothle_label, "gatt connecting..."); - elm_object_disabled_set(this->bluetoothle_btn, EINA_TRUE); + this->remote_server_address = device_info->remote_address; + + result = bt_device_create_bond(this->remote_server_address); + RETM_IF(result != BT_ERROR_NONE, "bt_device_create_bond fail > Error = %s", get_bluetooth_error(result)); + } @@ -1164,16 +1491,40 @@ static void _sevice_selected_cb(void *data, Evas_Object *obj, void *event_info) this = evas_object_data_get(obj, "bluetooth_view"); RETM_IF(!this, "view is NULL"); + this->service_exists = true; + this->will_back_cb_removed = false; + elm_list_clear(this->bluetoothle_list); bt_gatt_h service_h = (bt_gatt_h)data; this->service_h = service_h; - DBG("gatt_handle type service"); - result = bt_gatt_service_foreach_characteristics(service_h, _bt_gatt_foreach_characterstics_cb, this); + char* uuid; + result = bt_gatt_get_uuid(service_h, &uuid); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_get_uuid error: %s", get_bluetooth_error(result)); + DBG("selected service uuid %s", uuid); + + if(!strcmp(uuid, "0000180f-0000-1000-8000-00805f9b34fb")) + { + DBG("Battery Service"); + this->is_battery_svc_selected = true; + } + else if(!strcmp(uuid, "00001803-0000-1000-8000-00805f9b34fb")) + { + DBG("Link Loss Service"); + this->is_link_loss_svc_selected = true; + } + else + { + DBG("NO Service"); + } + + + DBG("gatt_handle type battery_service"); + result = bt_gatt_service_foreach_characteristics(this->service_h, _bt_gatt_foreach_characterstics_cb, this); RETM_IF(result != BT_ERROR_NONE, "bt_gatt_service_foreach_characteristics failed --> error: %s", get_bluetooth_error(result)); - result = bt_gatt_service_foreach_included_services(service_h, _bt_gatt_foreach_included_service, this); + result = bt_gatt_service_foreach_included_services(this->service_h, _bt_gatt_foreach_included_service, this); RETM_IF(result != BT_ERROR_NONE, "bt_gatt_service_foreach_included_services failed --> error: %s", get_bluetooth_error(result)); set_control_btn_state(SERVICE_EXPANDED, this); @@ -1239,13 +1590,8 @@ static void _descriptor_selected_cb(void *data, Evas_Object *obj, void *event_in result = bt_gatt_characteristic_get_descriptor(this->characterstic_h, uuid, &descriptor); RETM_IF(result != BT_ERROR_NONE,"bt_gatt_characteristic_get_descriptor error: %s", get_bluetooth_error(result)); - this->descriptor_h = descriptor; - this->is_int = true; - - elm_object_text_set(this->read_btn, "Read int"); - elm_object_text_set(this->write_btn, "Write int"); - set_control_btn_state(DESCRIPTORS_SELECTED, this); - + this->gatt_handle = descriptor; + set_control_btn_state(BATTERY_DESCRIPTORS_SELECTED, this); SAFE_DELETE(uuid); } @@ -1262,7 +1608,7 @@ static void _characteristic_selected_cb(void *data, Evas_Object *obj, void *even DBG(" _characteristic_selected_cb "); RETM_IF(!data, "data is NULL"); - + int result; bluetoothle_view *this; @@ -1270,15 +1616,27 @@ static void _characteristic_selected_cb(void *data, Evas_Object *obj, void *even RETM_IF(!this, "view is NULL"); char* uuid = (char*)data; - bt_gatt_h characteristic_h; result = bt_gatt_service_get_characteristic(this->service_h, uuid, &characteristic_h); RETM_IF(result != BT_ERROR_NONE, "bt_gatt_service_get_characteristic error: %s", get_bluetooth_error(result)); + // + result = bt_gatt_client_set_characteristic_value_changed_cb(characteristic_h, _bt_gatt_client_characteristic_value_changed_cb,this); + DBG("bt_gatt_client_set_characteristic_value_changed_cb error: %s", get_bluetooth_error(result)); + + this->gatt_handle = characteristic_h; + this->characterstic_h = this->gatt_handle; - this->characterstic_h = characteristic_h; + DBG("Char Handle on select: %x", this->gatt_handle); - set_control_btn_state(CHARACTERISTIC_SELECTED, this); + if(this->is_battery_svc_selected) + { + set_control_btn_state(BATTERY_CHARACTERISTIC_SELECTED, this); + } + else if(this->is_link_loss_svc_selected) + { + set_control_btn_state(LINK_LOSS_CHARACTERISTIC_SELECTED, this); + } } @@ -1291,7 +1649,7 @@ static void _characteristic_selected_cb(void *data, Evas_Object *obj, void *even */ static void _bt_gatt_connection_state_changed_cb(int result, bool connected, const char *remote_address, void *user_data) { - DBG("_bt_gatt_connection_state_changed_cb: %d", result); + DBG("_bt_gatt_connection_state_changed_cb: %s", get_bluetooth_error(result)); RETM_IF(NULL == user_data, "data is NULL"); bluetoothle_view *this = NULL; this = (bluetoothle_view*)user_data; @@ -1307,30 +1665,59 @@ static void _bt_gatt_connection_state_changed_cb(int result, bool connected, con if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_CLIENT) { elm_list_clear(this->bluetoothle_list); + ret = bt_gatt_client_create(remote_address, &this->client); RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_client_create error: %s", get_bluetooth_error(ret)); set_control_btn_state(SERVICE_LISTED, this); + + g_list_free_full(this->services_list, log_list_free_func_cb); + this->services_list = NULL; + ret = bt_gatt_client_foreach_services(this->client, _bt_gatt_foreach_services_cb, this); RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_client_foreach_services error: %s", get_bluetooth_error(ret)); char* client_remote_address; ret = bt_gatt_client_get_remote_address(this->client, &client_remote_address); RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_client_get_remote_address error: %s", get_bluetooth_error(ret)); + DBG("remote_address : %s", remote_address); DBG("client_remote_address: %s", client_remote_address); char* str; str = format_string("remote address: %s", client_remote_address); - //DBG("3.............."); elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); SAFE_DELETE(str); + + services_list_show(this); + } + + else if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_SERVER) + { + this->client_address = (char*)remote_address; + } } else { - elm_object_text_set(this->bluetoothle_label, "gatt connection failed"); + elm_object_text_set(this->bluetoothle_label, "Disconnected"); + if(this->view->tbt_info->apptype == TBT_APP_BLE_GATT_CLIENT) + { + ret = bt_gatt_client_destroy(this->client); + RETM_IF(ret != BT_ERROR_NONE, "bt_gatt_client_destroy error: %s", get_bluetooth_error(ret)); + + if(this->is_bonded) + { + ret = bt_device_destroy_bond(this->remote_server_address); + RETM_IF(ret != BT_ERROR_NONE, "bt_device_destroy_bond error: %s", get_bluetooth_error(ret)); + + } + else + { + DBG("bond not created"); + } + } } @@ -1356,10 +1743,52 @@ void _app_destroy_cb(void* this) if(view->view->tbt_info->apptype == TBT_APP_BLE_GATT_CLIENT) { bt_adapter_le_stop_scan(); - result = bt_gatt_client_destroy(view->client); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_client_destroy error: %s", get_bluetooth_error(result)); - result = bt_gatt_client_unset_characteristic_value_changed_cb(view->characterstic_h); - RETM_IF(result != BT_ERROR_NONE, "bt_gatt_client_unset_characteristic_value_changed_cb error: %s", get_bluetooth_error(result)); + } + else if(view->view->tbt_info->apptype == TBT_APP_BLE_GATT_SERVER) + { + result = bt_adapter_le_stop_advertising(view->advertiser); + RETM_IF(result != BT_ERROR_NONE, "bt_adapter_le_stop_advertising error: %s", get_bluetooth_error(result)); + + + DBG("Destroying battery service"); + if(view->battery_descriptor != NULL) + { + result = bt_gatt_descriptor_destroy(view->battery_descriptor); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_descriptor_destroy error: %s", get_bluetooth_error(result)); + } + if(view->battery_characteristic != NULL) + { + result = bt_gatt_characteristic_destroy(view->battery_characteristic); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_characteristic_destroy error: %s", get_bluetooth_error(result)); + } + if(view->battery_service != NULL) + { + result = bt_gatt_service_destroy(view->battery_service); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_service_destroy error: %s", get_bluetooth_error(result)); + } + + DBG("Destroying link loss service"); + if(view->link_loss_characteristic != NULL) + { + result = bt_gatt_characteristic_destroy(view->link_loss_characteristic); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_characteristic_destroy error: %s", get_bluetooth_error(result)); + } + if(view->link_loss_service != NULL) + { + result = bt_gatt_service_destroy(view->link_loss_service); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_service_destroy error: %s", get_bluetooth_error(result)); + } + + if(view->server_handle != NULL) + { + result = bt_gatt_server_unregister_all_services(view->server_handle); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_server_unregister_all_services error: %s", get_bluetooth_error(result)); + + result = bt_gatt_server_destroy(view->server_handle); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_server_destroy error: %s", get_bluetooth_error(result)); + } + result = bt_gatt_server_deinitialize(); + RETM_IF(result != BT_ERROR_NONE, "bt_gatt_server_deinitialize error: %s", get_bluetooth_error(result)); } result = bt_gatt_unset_connection_state_changed_cb(); RETM_IF(result != BT_ERROR_NONE, "bt_gatt_unset_connection_state_changed_cb error: %s", get_bluetooth_error(result)); @@ -1368,7 +1797,124 @@ void _app_destroy_cb(void* this) SAFE_DELETE(view); } +static void bluetooth_le_advertise(void* user_data) +{ + DBG("bluetooth_le_advertise"); + RETM_IF(NULL == user_data, "data is NULL"); + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + + int result; + + result = bt_adapter_le_create_advertiser(&this->advertiser); + RETM_IF(result != BT_ERROR_NONE, "bt_adapter_le_create_advertiser error: %s", get_bluetooth_error(result)); + + int mode = BT_ADAPTER_LE_ADVERTISING_MODE_LOW_LATENCY; + result = bt_adapter_le_set_advertising_mode(this->advertiser, mode); + RETM_IF(result != BT_ERROR_NONE, "bt_adapter_le_set_advertising_mode error: %s", get_bluetooth_error(result)); + // + char* battery_svc_uuid_16 = "180f"; + char* link_loss_svc_uuid_16 = "1803"; + int appearance = 1000; + + result = bt_adapter_le_add_advertising_service_uuid(this->advertiser, BT_ADAPTER_LE_PACKET_ADVERTISING, link_loss_svc_uuid_16); + result = bt_adapter_le_add_advertising_service_uuid(this->advertiser, BT_ADAPTER_LE_PACKET_ADVERTISING, battery_svc_uuid_16); + result = bt_adapter_le_set_advertising_appearance(this->advertiser, BT_ADAPTER_LE_PACKET_ADVERTISING, appearance); + result = bt_adapter_le_set_advertising_tx_power_level(this->advertiser, BT_ADAPTER_LE_PACKET_ADVERTISING, true); + + + result = bt_adapter_le_start_advertising_new(this->advertiser, _bt_adapter_le_advertising_state_changed_cb, this); + RETM_IF(result != BT_ERROR_NONE, "bt_adapter_le_start_advertising_new error: %s", get_bluetooth_error(result)); +} + +static void _bt_adapter_le_advertising_state_changed_cb(int result, bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e adv_state, void *user_data) +{ + DBG("_bt_adapter_le_advertising_state_changed_cb"); +} + + +static void _bt_gatt_server_read_value_requested_cb(const char *remote_address, int request_id, bt_gatt_server_h server, bt_gatt_h gatt_handle, int offset, void *user_data) +{ + DBG("_bt_gatt_server_read_value_requested_cb"); + + RETM_IF(NULL == user_data, "data is NULL"); + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + + char* str = format_string("read requested"); + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); + SAFE_DELETE(str); + + char char_value_1[4] = {65, 66, 67,0}; + int resp_status = BT_ERROR_NONE; + int result = bt_gatt_server_send_response(request_id, BLUETOOTH_GATT_REQUEST_TYPE_READ, offset, resp_status, char_value_1, 3 - offset); + DBG("bt_gatt_server_send_response %s", get_bluetooth_error(result)); + + str = format_string("response sent %s", char_value_1); + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); + SAFE_DELETE(str); + + + elm_list_go(this->bluetoothle_list); +} + +static void _bt_gatt_server_characteristic_notification_state_changed_cb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle, void *user_data) +{ + DBG("_bt_gatt_server_characteristic_notification_state_changed_cb"); +} + +static void _bt_gatt_server_write_value_requested_cb(const char *remote_address, int request_id, bt_gatt_server_h server, bt_gatt_h gatt_handle, int offset, const char *value, int len, void *user_data) +{ + DBG("_bt_gatt_server_write_value_requested_cb"); + RETM_IF(NULL == user_data, "data is NULL"); + bluetoothle_view *this = NULL; + this = (bluetoothle_view*)user_data; + RETM_IF(NULL == this, "view is NULL"); + int i, resp_status = BT_ERROR_NONE; + + char* str = format_string("write requested"); + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); + SAFE_DELETE(str); + + str = format_string("remote address: %s", remote_address); + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); + SAFE_DELETE(str); + + str = format_string("offset: %d", offset); + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); + SAFE_DELETE(str); + + str = format_string("length: %d", len); + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); + SAFE_DELETE(str); + + + DBG("remote_address : %s", remote_address); + DBG("offset : %d", offset); + DBG("len [%d] : ", len); + + char val_str[128]={'\0',}; + + for (i = 0; i < len; i++) + { + DBG("%d ", value[i]); + snprintf(val_str, sizeof(val_str), "%d", value[i]); + + } + + str = format_string("value: %s", val_str); + elm_list_item_append(this->bluetoothle_list, str, NULL, NULL, NULL, NULL); + SAFE_DELETE(str); + + bt_gatt_server_send_response(request_id, + BLUETOOTH_GATT_REQUEST_TYPE_WRITE, offset, + resp_status, NULL, 0); + + elm_list_go(this->bluetoothle_list); +} /** * @function get_bluetooth_error * @since_tizen 2.3 diff --git a/tbtcoreapp/src/view/tbt-genlist-view.c b/tbtcoreapp/src/view/tbt-genlist-view.c index e55050c..99194f3 100644 --- a/tbtcoreapp/src/view/tbt-genlist-view.c +++ b/tbtcoreapp/src/view/tbt-genlist-view.c @@ -665,9 +665,16 @@ static void _gl_item_selected_cb(void *data, Evas_Object *obj EINA_UNUSED, void #endif #ifdef TBT_MODULE_BLE + #ifdef TBT_MODULE_BLE_GATT_CLIENT case TBT_APP_BLE_GATT_CLIENT: bluetoothle_view_add(view->navi, info, it); break; + #endif + #ifdef TBT_MODULE_BLE_GATT_SERVER + case TBT_APP_BLE_GATT_SERVER: + bluetoothle_view_add(view->navi, info, it); + break; + #endif #endif #ifdef TBT_MODULE_BT_CALLBACK_TEST