Page Example

Bluetooth LE Scanner Sample Overview

Mobile native

The Bluetooth LE Scanner sample application demonstrates how you can scan for LE devices and connect to a device.

The following figure illustrates the application screens.

Figure: Bluetooth LE Scanner screens

Bluetooth LE Scanner screens Bluetooth LE Scanner screens

Click BLE Scan to find devices. After the device is connected, you can see the service UUID of the LE device.

Implementation

To implement the Bluetooth LE Scanner:

  1. When BLE Scan is clicked, the application calls the bt_mgr_initialize() function to check whether Bluetooth is switched on. If Bluetooth is off, the application calls the Bluetooth ON/OFF operation to switch Bluetooth on.

    Figure: Bluetooth ON/OFF application

    Bluetooth ON/OFF application Bluetooth ON/OFF application

    void
    bt_mgr_initialize(void *data, bt_mgr_type type)
    {
       appdata_s *ad = NULL;
       bt_adapter_state_e bt_ad_state = BT_ADAPTER_DISABLED;
       bt_adapter_visibility_mode_e bt_ad_visibility = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
       int ret = 0;
       int duration = 1;
    
       ad = (appdata_s *)data;
       ret_if(!ad);
    
       ret = bt_initialize();
       ret_if(ret != BT_ERROR_NONE);
    
       ret = bt_adapter_get_state(&bt_ad_state);
       ret_if(ret != BT_ERROR_NONE);
    
       if (bt_ad_state == BT_ADAPTER_DISABLED)
          _onoff_operation();
       else
          _search_layout_create(ad);
    }
    
    static void
    _onoff_operation(void)
    {
       int ret = 0;
       app_control_h service = NULL;
    
       app_control_create(&service);
       ret_if(!service);
    
       app_control_set_operation(service, "APP_CONTROL_OPERATION_SETTING_BT_ENABLE");
       ret = app_control_send_launch_request(service, NULL, NULL);
       if (ret != APP_CONTROL_ERROR_NONE)
       {
          _E("Failed to relaunch Bluetooth On/off app");
       }
    
       app_control_destroy(service);
    }
    

    After the bt_mgr_initialize() function is called and Bluetooth is on, the application draws proper layouts according to its current role (client or server).

  2. To scan for LE devices, click BLE Scan. The application draws its own layout using the _search_layout_create() function, which is called by the bt_mgr_initialize() function. The layout contains a list of the found devices.

    static void
    _search_layout_create(appdata_s *ad)
    {
       int ret = 0;
    
       ret_if(!ad);
       ret_if(!ad->navi);
    
       ad->role = BT_SOCKET_CLIENT;
    
       s_info.list = elm_list_add(ad->navi);
       ret_if(!s_info.list);
    
       evas_object_event_callback_add(s_info.list, EVAS_CALLBACK_DEL, _on_search_del_cb, ad);
       evas_object_size_hint_weight_set(s_info.list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
       evas_object_size_hint_align_set(s_info.list, EVAS_HINT_FILL, EVAS_HINT_FILL);
       elm_list_go(s_info.list);
       elm_naviframe_item_push(ad->navi, "Search Friends", NULL, NULL, s_info.list, NULL);
    
       ret = bt_gatt_set_connection_state_changed_cb(_bt_gatt_connection_state_changed_cb, ad);
       ret_if(ret != BT_ERROR_NONE);
    
       _discovery_start(ad);
    }
    
  3. While drawing the list, the application starts finding devices with the _discovery_start() function. Set the device discovery state changed callback and update the list whenever a new device is found.

    static void
    _discovery_start(appdata_s *ad)
    {
       bt_error_e ret = BT_ERROR_NONE;
    
       ret_if(!ad);
       ret_if(ad->bt);
    
       ad->bt = TRUE;
    
       ret = bt_adapter_le_start_scan(_bt_adapter_le_scan_result_cb, ad);
       ret_if(ret != BT_ERROR_NONE);
    }
    
  4. If an item on the list is clicked, the application starts to bond with the target device, and requests to connect to the target server.

    static void
    _click_friend_item_cb(void *data, Evas_Object *obj, void *event_info)
    {
       Evas_Object *noti = NULL;
       Elm_Object_Item *item = NULL;
       bt_adapter_device_discovery_info_s *info = NULL;
       bt_error_e ret = BT_ERROR_NONE;
       int result;
    
       ret_if(!obj);
    
       info = (bt_adapter_device_discovery_info_s *)data;
       ret_if(!info);
       s_info.info = info;
       item = elm_list_selected_item_get(obj);
       ret_if(!item);
       elm_list_item_selected_set(item, EINA_FALSE);
    
       result = bt_adapter_le_stop_scan();
       bt_gatt_connect(info->remote_address, false);
    
       elm_list_clear(s_info.list);
       elm_list_item_append(s_info.list, "Connecting...", NULL, NULL, NULL, NULL);
       elm_list_go(s_info.list);
    }
    
  5. When the application is successfully connected with the target, the _bt_gatt_connection_state_changed_cb() function is called and the application shows the service UUID list of the connected device.

    static void
    _bt_gatt_connection_state_changed_cb(int result, bool connected, const char *remote_address, void *user_data)
    {
       Evas_Object *noti = NULL;
       appdata_s *ad = (appdata_s *)user_data;
       int ret;
          _D("gatt remote address: %s", remote_address);
    
       if (connected) {
          elm_list_item_append(s_info.list, "Connected!!", NULL, NULL, NULL, NULL);
          elm_list_go(s_info.list);
    
          ret = bt_gatt_client_create(remote_address, &ad->client);
          if (ret != BT_ERROR_NONE)
             _D("Failed to create gatt client");
          else
             _D("gatt client created");
    
          elm_list_item_append(s_info.list, "[Services UUID]", NULL, NULL, NULL, NULL);
          elm_list_go(s_info.list);
    
          ret = bt_gatt_client_foreach_services(ad->client, _bt_gatt_foreach_services_cb, ad);
          if (ret != BT_ERROR_NONE)
             _D("Failed to foreach services");
       }
       else
          elm_list_item_append(s_info.list, "Disconnected..", NULL, NULL, NULL, NULL);
    
       elm_list_go(s_info.list);
    }