[TBT][tizen_3.0_mobile][Gatt Server Module added, Gatt Client Module Updated] 83/84783/2
authornazib.ullah <nazib.ullah@samsung.com>
Mon, 22 Aug 2016 10:01:30 +0000 (16:01 +0600)
committernazib.ullah <nazib.ullah@samsung.com>
Mon, 22 Aug 2016 10:05:29 +0000 (16:05 +0600)
Change-Id: I7befabfe60c73dbb0c302fb5bc2daadbc684d608

release/binary-armv7l/org.tizen.tbtcoreapp-1.0.0-arm.tpk
release/binary-x86/org.tizen.tbtcoreapp-1.0.0-i386.tpk
tbtcoreapp/inc/model/tbt-info.h
tbtcoreapp/inc/utils/app_module_config.h
tbtcoreapp/src/model/tbt-list.c
tbtcoreapp/src/view/tbt-bluetoothle-view.c
tbtcoreapp/src/view/tbt-genlist-view.c

index 259134776d0f6d03cb88e6f6fddfc18da605aea6..8134e2b263a51a5870ca07f090aaec30636698fa 100644 (file)
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
index 86a2ef5c9e08ac24784614c94a16096dc3a42231..cd2dd175d0648aed28a44548d98807ccd415a80f 100644 (file)
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
index 1c5de2dc22b15387f41aff1135de60fe402d0980..e860e3ec0624f71c150175b237a6f53dd5f5e186 100644 (file)
@@ -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,
index bb6518e282aa94c1a34bed1f8b5f41674a222882..02c236511f1a4c23ee50bccc1c5da31cd8bbd1c8 100644 (file)
@@ -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
index f004b54bbd0494fea666f31a21f16dc574fbc593..0e609ccac8365064c20fa060c6f3bcf580a4dc5d 100644 (file)
@@ -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
index 1f05243a500381235a243b1f96b24e390dc5a2bf..3ab97ef7b2932f7567a6a2bb93469b12393be3d7 100644 (file)
 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; i<value_length; i++)
+       {
+               DBG("value : %d", value[i]);
+       }
+
+       char trimmed_str[128];
+       strncpy(trimmed_str, value, value_length);
+       trimmed_str[value_length] = 0;
+
+       DBG("value: %s, value_length: %d", trimmed_str, value_length);
 
        char* str;
-       str = format_string("value %s len %d", value, value_length);
+       str = format_string("value %s len %d", trimmed_str, value_length);
        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);
+
        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
index e55050c5df8e314af3749a432cdebb7fd2895a4a..99194f3ef9b8abecf8082f2e67fac16e94751dd5 100644 (file)
@@ -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