Hello,
i am developing app for samsung gear s2. Application scan BLE device, i have to read data from chip. Chip will give data if we fire some command. so i used GATT server-client mechanism for that.
I able to Scan - > Read data-> Set value -> Not able read and Not able write data to the chip.
I used two button scan - stop. when press scan app starts scanning once i found my beacon i will stop scan process and implement GATT process.
Succesfull: create client , Get remote address, Read Service, charateristics, descripter, Set value 2 (pass hex value ) to descriptor and set +++ (pass hex) to charateristic,
Fail: to write command(value) to descriptor. same as pass +++ command to charateristics but failed to write
Please see below logs, code. and if i am going wrong plz correct me.
Logs:
03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ): Bluetooth adapter is enabled 03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Gatt connection succesfully 03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [bt_adapter_le_start_scan] Succesfully. 03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : TX Power level = 8
03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Manufacturer data[ID:0363, 0x5800...(len:20)] 03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Device name = FreeXip BGM BA-00023 l 03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Remote Address: 00:0B:57:00:E1:C3 03-24 20:01:08.163 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : ÿcX, adv_data_lenL:30, scan_data: FreeXip BGM BA-00023 lqˆA%, scan_data_len:24, rssi:-57 03-23 19:26:07.478 : INFO / basicbluetoothdemo ( 4417 : 4417 ) : RemoveString1 FreeXip 03-23 19:26:07.478 : INFO / basicbluetoothdemo ( 4417 : 4417 ) : RemoveString1 BGM 03-23 19:26:07.478 : INFO / basicbluetoothdemo ( 4417 : 4417 ) : RemoveString1 BA-00023l 03-24 20:01:08.308 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Formated Final Device name = BA-0002 03-24 20:01:08.308 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : Remoteaddres-gattopr 00:0B:57:00:E1:C3 03-24 20:01:08.368 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : Connected to our LE device. 03-24 20:01:08.888 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : Client created 03-24 20:01:08.888 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : Successfully get remote address 03-24 20:01:08.888 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : Remote address 00:0B:57:00:E1:C3 03-24 20:01:08.888 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : info->Remote: Remote address 00:0B:57:00:E1:C3 03-24 20:01:08.888 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [1 / 4] uuid : (1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0) 03-24 20:01:08.988 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [1 / 2] uuid : (f7bf3564-fb6d-4e53-88a4-5e37e0326063) 03-24 20:01:08.993 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [2 / 2] uuid : (984227f3-34fc-4045-a5d0-2c581f81a153) 03-24 20:01:08.993 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [2 / 4] uuid : (-xxxx-xxxx-xxxx-xxxxxx) -> service id 03-24 20:01:09.033 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [1 / 1] uuid : (e7adxx-xxxx-xxxxx-xxxx-xxxxxx) -characterstics id 03-24 20:01:09.128 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [1 / 2] uuid : (00002902-xxxx-1xxx-8xxxx-0xxxxx) -> descriptor 03-24 20:01:09.128 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [2 / 2] uuid : (xxxxxx-xxxxx-xxxxx-xxxxx-xxxxxxxxxxxx) 03-24 20:01:09.128 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [3 / 4] uuid : (0000180a-0000-1000-8000-00805f9b34fb) 03-24 20:01:09.233 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [1 / 2] uuid : (00002a29-0000-1000-8000-00805f9b34fb) 03-24 20:01:09.233 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [2 / 2] uuid : (00002a24-0000-1000-8000-00805f9b34fb) 03-24 20:01:09.233 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [4 / 4] uuid : (00001800-0000-1000-8000-00805f9b34fb) 03-24 20:01:09.333 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [1 / 2] uuid : (00002a00-0000-1000-8000-00805f9b34fb) 03-24 20:01:09.333 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : [2 / 2] uuid : (00002a01-0000-1000-8000-00805f9b34fb) 03-24 20:01:09.338 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : services found 03-24 20:01:09.338 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : bt_gatt_client_get_service is success 03-24 20:01:09.338 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : bt_gatt_client_get_characteristic is success : 03-24 20:01:09.338 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : bt_gatt_characteristic_get_descriptor is success 03-24 20:01:09.338 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Failed to set write type-desc2 type 03-24 20:01:09.338 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : bt_gatt_set_value (0x02) success* 03-24 20:01:09.338 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : bt_gatt_set_value (0x02) success 03-24 20:01:09.363 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Successfully set write- 0x02 03-24 20:01:09.363 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Success - control point 03-24 20:01:09.363 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Successfully set write type 03-24 20:01:09.363 : INFO / basicbluetoothdemogatt ( 3023 : 3023 ) : bt_gatt_set_value(+++) success 03-24 20:01:09.363 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Failed to set write 03-24 20:01:09.363 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : bt_gatt_client_read_value-(+++) failed* 03-24 20:01:09.363 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : bt_gatt_client_read_value-(+++) failed: -115 03-24 20:01:09.398 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : bt_gatt_client_set_characteristic_value_changed_cb Success 03-24 20:01:09.513 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Successfully disconnect 03-24 20:01:09.528 : INFO / basicbluetoothdemo ( 3023 : 3023 ) : Write Fail for uuid: (00002902-xxxx-1xxx-8xxxx-0xxxxxx) -> descripter 1
Code:
#include "basicbluetoothdemo.h" #include <bluetooth.h> #include <dlog.h> #include <glib.h> /* For GList */ #include <string.h> #define READ_CURRENT_RELAY_TIME 0x2b0x2b0x2b0x0D typedef struct appdata { Evas_Object *win; Evas_Object *conform; Evas_Object *label; Evas_Object *button; } appdata_s; bt_error_e ret; bt_gatt_client_h client = NULL; const char *remoteaddress = NULL; static void create_base_gui(appdata_s *ad); //call back methods: static void btn_stop_cb(void *data, Evas_Object *obj, void *event_info); static void btn_start_cb(void *data, Evas_Object *obj, void *event_info); void showPopup(char* msg); void dismissed_cb(void *data, Evas_Object *obj, void *event_info); //**************************** BLE connection establish **************************************** int bt_onoff_operation(void); static void checkingBluetoothAdapter(); void socket_connection_state_changed(int result, bt_socket_connection_state_e connection_state, bt_socket_connection_s *connection, void *user_data); void adapter_state_changed_cb(int result, bt_adapter_state_e adapter_state, void* user_data); void adapter_device_discovery_state_changed_cb(int result, bt_adapter_device_discovery_state_e discovery_state, bt_adapter_device_discovery_info_s *discovery_info, void* user_data); /*void adapter_le_device_discovery_state_changed_cb(int result, bt_adapter_le_device_discovery_state_e discovery_state, bt_adapter_le_device_discovery_info_s *discovery_info, void* user_data);*/ char* getFinalDeviceName(char* main, char* substring); //for ble gatt cb void gatt_operation(char* remoteaddres); //for ble scan method- temporary void gatt_operation2(const char* remoteaddress); //scan beacon void __bt_adapter_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data); // gatt connection void __bt_gatt_connection_state_changed_cb(int result, bool connected, const char *remote_address, void *user_data); //Discover the service, characteristics, and descriptors of the remote service: bool __bt_gatt_client_foreach_svc_cb(int total, int index, bt_gatt_h svc_handle, void *data); //to discover the characteristic descriptors: bool __bt_gatt_client_foreach_chr_cb(int total, int index, bt_gatt_h chr_handle, void *data); //to get the descriptor data bool __bt_gatt_client_foreach_desc_cb(int total, int index, bt_gatt_h desc_handle, void *data); //read value void __bt_gatt_client_read_complete_cb(int result, bt_gatt_h gatt_handle, void *data); //write value void __bt_gatt_client_write_complete_cb(int result, bt_gatt_h gatt_handle, void *data); //Read value void __bt_gatt_client_read_complete_cb(int result, bt_gatt_h gatt_handle, void *data); //set value int __bt_gatt_client_set_value(char *type, char *value, bt_gatt_h h); //call back for write complete value void __bt_gatt_client_write_complete_cb(int result, bt_gatt_h gatt_handle, void *data); //register callback if any value is change void __bt_gatt_client_value_changed_cb(bt_gatt_h chr, char *value, int len, void *user_data); static void win_delete_request_cb(void *data, Evas_Object *obj, void *event_info) { ui_app_exit(); } static void win_back_cb(void *data, Evas_Object *obj, void *event_info) { appdata_s *ad = data; /* Let window go to hide state. */ elm_win_lower(ad->win); } static void create_base_gui(appdata_s *ad) { /* Window */ ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE); elm_win_autodel_set(ad->win, EINA_TRUE); if (elm_win_wm_rotation_supported_get(ad->win)) { int rots[4] = { 0, 90, 180, 270 }; elm_win_wm_rotation_available_rotations_set(ad->win, (const int *) (&rots), 4); } evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL); eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad); /* Conformant */ ad->conform = elm_conformant_add(ad->win); elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW); elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE); evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(ad->win, ad->conform); evas_object_show(ad->conform); /*Label*/ ad->label = elm_label_add(ad->conform); elm_object_text_set(ad->label, "<align=center>BLE</center>"); evas_object_move(ad->label, 0, 10); elm_object_content_set(ad->conform, ad->label); evas_object_show(ad->label); //evas_object_resize(btn, 200, 50); /* Button for bluetooth scan*/ Evas_Object *btn = elm_button_add(ad->conform); elm_object_text_set(btn, "Start"); //evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_smart_callback_add(btn, "clicked", btn_start_cb, ad); evas_object_move(btn, 100, 110); evas_object_resize(btn, 150, 40); evas_object_show(btn); /* Button for bluetooth scan*/ Evas_Object *btnStop = elm_button_add(ad->conform); elm_object_text_set(btnStop, "Stop"); //evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_smart_callback_add(btnStop, "clicked", btn_stop_cb, ad); evas_object_move(btnStop, 100, 250); evas_object_resize(btnStop, 150, 40); evas_object_show(btnStop); /* Show window after base gui is set up */ evas_object_show(ad->win); } static bool app_create(void *data) { /* Hook to take necessary actions before main event loop starts Initialize UI resources and application's data If this function returns true, the main loop of application starts If this function returns false, the application is terminated */ appdata_s *ad = data; create_base_gui(ad); dlog_print(DLOG_ERROR, LOG_TAG, "app-create"); return true; } static void app_control(app_control_h app_control, void *data) { /* Handle the launch request. */ dlog_print(DLOG_ERROR, LOG_TAG, "app-control"); } static void app_pause(void *data) { /* Take necessary actions when application becomes invisible. */ dlog_print(DLOG_ERROR, LOG_TAG, "app-pause"); } static void app_resume(void *data) { /* Take necessary actions when application becomes visible. */ dlog_print(DLOG_ERROR, LOG_TAG, "app-resume"); } static void app_terminate(void *data) { /* Release all resources. */ dlog_print(DLOG_ERROR, LOG_TAG, "app-terminate"); } static void ui_app_lang_changed(app_event_info_h event_info, void *user_data) { /*APP_EVENT_LANGUAGE_CHANGED*/ char *locale = NULL; system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, &locale); elm_language_set(locale); free(locale); return; } static void ui_app_orient_changed(app_event_info_h event_info, void *user_data) { /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/ return; } static void ui_app_region_changed(app_event_info_h event_info, void *user_data) { /*APP_EVENT_REGION_FORMAT_CHANGED*/ } static void ui_app_low_battery(app_event_info_h event_info, void *user_data) { /*APP_EVENT_LOW_BATTERY*/ } static void ui_app_low_memory(app_event_info_h event_info, void *user_data) { /*APP_EVENT_LOW_MEMORY*/ } int main(int argc, char *argv[]) { appdata_s ad = { 0, }; int ret = 0; ui_app_lifecycle_callback_s event_callback = { 0, }; app_event_handler_h handlers[5] = { NULL, }; event_callback.create = app_create; event_callback.terminate = app_terminate; event_callback.pause = app_pause; event_callback.resume = app_resume; event_callback.app_control = app_control; ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad); ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad); ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad); ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad); ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad); ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]); ret = ui_app_main(argc, argv, &event_callback, &ad); if (ret != APP_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret); } return ret; } /************************************************************************************************************ ********************************** Method implementation *********************************** ************************************************************************************************************/ //button call back method. static void btn_stop_cb(void *data, Evas_Object *obj, void *event_info) { //stop scanning ret = bt_adapter_le_stop_scan(); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "[bt_adapter_le_stop_scan] failed."); } //Disconnect : got null value; ret = bt_gatt_disconnect(remoteaddress); dlog_print(DLOG_INFO, LOG_TAG, "Remote address of FxChip %s", remoteaddress); dlog_print(DLOG_INFO, LOG_TAG, "%s", ret == BT_ERROR_NONE ? "Successfully disconnect - stop call" : "Fail to disconnect - stop call "); //De-register the GATT connection callback ret = bt_gatt_unset_connection_state_changed_cb(); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Failed to deregister"); } else dlog_print(DLOG_INFO, LOG_TAG, "Successfully deregister"); // Destroy the client if (client != NULL) { ret = bt_gatt_client_destroy(client); if (ret == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Successfully destroy client"); } else dlog_print(DLOG_INFO, LOG_TAG, "Falied to destroy client"); client = NULL; } } static void btn_start_cb(void *data, Evas_Object *obj, void *event_info) { //appdata_s* ad = data; ret = bt_initialize(); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "[bt_initialize] failed."); return; } int i = bt_onoff_operation(); dlog_print(DLOG_ERROR, LOG_TAG, "%d", i); //check adapter if bluetooth is found then start scanning otherwise not scan. checkingBluetoothAdapter(); } void create_popup(Evas_Object *parent, char* text) { Evas_Object *popup; popup = elm_popup_add(parent); elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, eext_popup_back_cb, parent); evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_object_text_set(popup, text); evas_object_show(popup); } void dismissed_cb(void *data, Evas_Object *obj, void *event_info) { evas_object_del(obj); } void showPopup(char* msg) { /* Create a popup */ appdata_s *ad; Evas_Object *popup; popup = elm_popup_add(ad->conform); //elm_object_part_text_set(popup, "Alert", "Bluetooth is off"); elm_object_text_set(popup, msg); evas_object_smart_callback_add(popup, "dismissed", dismissed_cb, ad); elm_popup_timeout_set(popup, 3.0); evas_object_show(popup); } /************************************************************************************************************ Bluetooth Setup ************************************************************************************************************/ int bt_onoff_operation(void) { int ret = 0; app_control_h service = NULL; app_control_create(&service); if (service == NULL) { dlog_print(DLOG_INFO, LOG_TAG, "service_create failed!\n"); return 0; } app_control_set_operation(service, "APP_CONTROL_OPERATION_SETTING_BT_ENABLE"); ret = app_control_send_launch_request(service, NULL, NULL); app_control_destroy(service); if (ret == APP_CONTROL_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Succeeded to Bluetooth On/Off app!\n"); return 0; } else { dlog_print(DLOG_INFO, LOG_TAG, "Failed to relaunch Bluetooth On/Off app!\n"); return -1; } return 0; } static void checkingBluetoothAdapter() { bt_adapter_state_e adapter_state; /* Check whether the Bluetooth adapter is enabled */ ret = bt_adapter_get_state(&adapter_state); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "[bt_adapter_get_state] failed"); return; } /* If the Bluetooth adapter is not enabled */ if (adapter_state == BT_ADAPTER_DISABLED) { dlog_print(DLOG_ERROR, LOG_TAG, "Bluetooth adapter is not enabled. You should enable Bluetooth!!"); } //Bluetooth adapter state changed ret = bt_adapter_set_state_changed_cb(adapter_state_changed_cb, NULL); if (ret != BT_ERROR_NONE) dlog_print(DLOG_ERROR, LOG_TAG, "[bt_adapter_set_state_changed_cb()] failed."); if (adapter_state == BT_ADAPTER_ENABLED) { dlog_print(DLOG_ERROR, LOG_TAG, "Bluetooth adapter is enabled"); //gatt connection ret = bt_gatt_set_connection_state_changed_cb( __bt_gatt_connection_state_changed_cb, NULL); if (ret == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Gatt connection succesfully"); } //socket created /* ret = bt_socket_set_connection_state_changed_cb( socket_connection_state_changed, NULL); if (ret == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Socket created successfully"); }*/ //BLE call ret = bt_adapter_le_start_scan(__bt_adapter_le_scan_result_cb, NULL); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "[bt_adapter_le_start_scan] failed."); } else { dlog_print(DLOG_ERROR, LOG_TAG, "[bt_adapter_le_start_scan] Succesfully."); } } } void adapter_state_changed_cb(int result, bt_adapter_state_e adapter_state, void* user_data) { if (result != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "[adapter_state_changed_cb] failed! result=%d", result); return; } if (adapter_state == BT_ADAPTER_ENABLED) { dlog_print(DLOG_INFO, LOG_TAG, "[adapter_state_changed_cb] Bluetooth is enabled!"); /* Get information about Bluetooth adapter */ char *local_address = NULL; bt_adapter_get_address(&local_address); dlog_print(DLOG_INFO, LOG_TAG, "[adapter_state_changed_cb] Adapter address: %s.", local_address); if (local_address) free(local_address); char *local_name; bt_adapter_get_name(&local_name); dlog_print(DLOG_INFO, LOG_TAG, "[adapter_state_changed_cb] Adapter name: %s.", local_name); if (local_name) free(local_name); /* Visibility mode of the Bluetooth device */ bt_adapter_visibility_mode_e mode; /* Duration until the visibility mode is changed so that other devices cannot find your device */ int duration = 1; bt_adapter_get_visibility(&mode, &duration); switch (mode) { case BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE: dlog_print(DLOG_INFO, LOG_TAG, "[adapter_state_changed_cb] Visibility: NON_DISCOVERABLE"); break; case BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE: dlog_print(DLOG_INFO, LOG_TAG, "[adapter_state_changed_cb] Visibility: GENERAL_DISCOVERABLE"); break; case BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE: dlog_print(DLOG_INFO, LOG_TAG, "[adapter_state_changed_cb] Visibility: LIMITED_DISCOVERABLE"); break; } } else { dlog_print(DLOG_INFO, LOG_TAG, "[adapter_state_changed_cb] Bluetooth is disabled!"); /* When you try to get device information by invoking bt_adapter_get_name(), bt_adapter_get_address(), or bt_adapter_get_visibility(), BT_ERROR_NOT_ENABLED occurs */ } } //for classic bluetooth: void adapter_device_discovery_state_changed_cb(int result, bt_adapter_device_discovery_state_e discovery_state, bt_adapter_device_discovery_info_s *discovery_info, void* user_data) { if (result != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "[adapter_device_discovery_state_changed_cb] failed! result(%d).", result); return; } GList** searched_device_list = (GList**) user_data; switch (discovery_state) { case BT_ADAPTER_DEVICE_DISCOVERY_STARTED: dlog_print(DLOG_INFO, LOG_TAG, "BT_ADAPTER_DEVICE_DISCOVERY_STARTED"); break; case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED: dlog_print(DLOG_INFO, LOG_TAG, "BT_ADAPTER_DEVICE_DISCOVERY_FINISHED"); break; case BT_ADAPTER_DEVICE_DISCOVERY_FOUND: dlog_print(DLOG_INFO, LOG_TAG, "BT_ADAPTER_DEVICE_DISCOVERY_FOUND"); if (discovery_info != NULL) { dlog_print(DLOG_INFO, LOG_TAG, "Device Address: %s", discovery_info->remote_address); dlog_print(DLOG_INFO, LOG_TAG, "Device Name is: %s", discovery_info->remote_name); bt_adapter_device_discovery_info_s * new_device_info = malloc( sizeof(bt_adapter_device_discovery_info_s)); if (new_device_info != NULL) { memcpy(new_device_info, discovery_info, sizeof(bt_adapter_device_discovery_info_s)); new_device_info->remote_address = strdup( discovery_info->remote_address); new_device_info->remote_name = strdup( discovery_info->remote_name); *searched_device_list = g_list_append(*searched_device_list, (gpointer) new_device_info); } } break; } } /************************************************************************************************************ BLE Scan ************************************************************************************************************/ //BLE Scan device call back void __bt_adapter_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data) { int i; bt_adapter_le_packet_type_e pkt_type = BT_ADAPTER_LE_PACKET_ADVERTISING; if (info == NULL) { dlog_print(DLOG_INFO, LOG_TAG, "No discovery_info!"); return; } if (info->adv_data_len > 31 || info->scan_data_len > 31) { dlog_print(DLOG_INFO, LOG_TAG, "###################"); bt_adapter_le_stop_scan(); dlog_print(DLOG_INFO, LOG_TAG, "###################"); return; } for (i = 0; i < info->adv_data_len; i++) { char **uuids; char *device_name; int tx_power_level; bt_adapter_le_service_data_s *data_list; int appearance; int manufacturer_id; char *manufacturer_data; int manufacturer_data_len; int count; pkt_type += i; if (pkt_type == BT_ADAPTER_LE_PACKET_ADVERTISING&& info->adv_data == NULL) continue; if (pkt_type == BT_ADAPTER_LE_PACKET_SCAN_RESPONSE&& info->scan_data == NULL) break; if (bt_adapter_le_get_scan_result_service_uuids(info, pkt_type, &uuids, &count) == BT_ERROR_NONE) { int i; for (i = 0; i < count; i++) { dlog_print(DLOG_INFO, LOG_TAG, "UUID[%d] = %s", i + 1, uuids[i]); g_free(uuids[i]); } g_free(uuids); } if (bt_adapter_le_get_scan_result_device_name(info, pkt_type, &device_name) == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Device name = %s", device_name); dlog_print(DLOG_INFO, LOG_TAG, "Remote Address: %s", info->remote_address); dlog_print(DLOG_INFO, LOG_TAG, "adv_data: %s, adv_data_lenL:%d, scan_data:%s, scan_data_len:%d, rssi:%d", info->adv_data, info->adv_data_len, info->scan_data, info->scan_data_len, info->rssi); //dlog_print(DLOG_INFO, LOG_TAG, "Packet type: %s",pkt_type); char* chipPrefixStr = "FreeXip BGM"; //find FreeXip BGM if (strstr(device_name, chipPrefixStr)) { bt_adapter_le_stop_scan(); //temporary stop scanning. //format device name for display char* finalDname = getFinalDeviceName(device_name, chipPrefixStr); dlog_print(DLOG_INFO, LOG_TAG, "Formated Final Device name = %s", finalDname); //list out @ glist list -finalDname //BLE GATT Operation starts here. gatt_operation2(info->remote_address); } } if (bt_adapter_le_get_scan_result_tx_power_level(info, pkt_type, &tx_power_level) == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "TX Power level = %d", tx_power_level); } if (bt_adapter_le_get_scan_result_service_solicitation_uuids(info, pkt_type, &uuids, &count) == BT_ERROR_NONE) { int i; for (i = 0; i < count; i++) { dlog_print(DLOG_INFO, LOG_TAG, "Solicitation UUID[%d] = %s", i + 1, uuids[i]); g_free(uuids[i]); } g_free(uuids); } if (bt_adapter_le_get_scan_result_service_data_list(info, pkt_type, &data_list, &count) == BT_ERROR_NONE) { int i; for (i = 0; i < count; i++) { dlog_print(DLOG_INFO, LOG_TAG, "Service Data[%d] = [0x%2.2X%2.2X:0x%.2X...]", i + 1, data_list[i].service_uuid[0], data_list[i].service_uuid[1], data_list[i].service_data[0]); bt_adapter_le_free_service_data_list(data_list, count); } } if (bt_adapter_le_get_scan_result_appearance(info, pkt_type, &appearance) == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Appearance = %d", appearance); } if (bt_adapter_le_get_scan_result_manufacturer_data(info, pkt_type, &manufacturer_id, &manufacturer_data, &manufacturer_data_len) == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "Manufacturer data[ID:%.4X, 0x%.2X%.2X...(len:%d)]", manufacturer_id, manufacturer_data[0], manufacturer_data[1], manufacturer_data_len); g_free(manufacturer_data); } } } void gatt_operation2(const char* remoteaddress) { //para dlog_print(DLOG_INFO, LOG_TAG_GATT, "Remoteaddres-gattopr %s", remoteaddress); //dlog_print(DLOG_INFO, LOG_TAG_GATT, "Remoteaddres-gattopr %s",finalDname); char *addr = NULL; ret = bt_gatt_connect(remoteaddress, false); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG_GATT, "Failed to connect LE device."); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "Connected to our LE device."); //GATT operation starts //Client creation ret = bt_gatt_client_create(remoteaddress, &client); if (ret == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG_GATT, "Client created"); //get remote address ret = bt_gatt_client_get_remote_address(client, &addr); if (ret == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG_GATT, "Successfully get remote address"); dlog_print(DLOG_INFO, LOG_TAG_GATT, "Remote address %s", addr); } remoteaddress = addr; dlog_print(DLOG_INFO, LOG_TAG_GATT, "info->Remote: Remote address %s", remoteaddress); //Get service name ret = bt_gatt_client_foreach_services(client, __bt_gatt_client_foreach_svc_cb, NULL); if (ret == BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG_GATT, "services found"); char *svc_uuid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx"; // Chip main service UUID- security reason place xxxx value. char *chr_uuid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"; // Characteristic UDID need to set (+++) command char *desc_uuid = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx"; // Descriptor - need to set 0x02 bt_gatt_h gatt_handle = NULL; bt_gatt_h svc = NULL; bt_gatt_h chr = NULL; bt_gatt_h desc = NULL; //get service - freelap service ret = bt_gatt_client_get_service(client, svc_uuid, &svc); if (ret == BT_ERROR_NO_DATA) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "BT_ERROR_NO_DATA: bt_gatt_client_get_service is failed : %d", ret); } else if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "bt_gatt_client_get_service is failed : %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "bt_gatt_client_get_service is success "); } //get characteristic ret = bt_gatt_service_get_characteristic(svc, chr_uuid, &chr); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "bt_gatt_service_get_characteristic is failed : %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "bt_gatt_client_get_characteristic is success :"); } //get descriptor ret = bt_gatt_characteristic_get_descriptor(chr, desc_uuid, &desc); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "bt_gatt_characteristic_get_descriptor failed : %d", ret); return; } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "bt_gatt_characteristic_get_descriptor is success"); } //--------------------set 0x02 Descriptor ------------------- //1) set type to desc. ret = bt_gatt_characteristic_set_write_type(desc, BT_GATT_WRITE_TYPE_WRITE); if (ret == BT_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "Successfully set write type-desc2 type"); else dlog_print(DLOG_INFO, LOG_TAG, "Failed to set write type-desc2 type"); //2) set value 0x02 ret = __bt_gatt_client_set_value("uint8", "0x02", desc); dlog_print(DLOG_INFO, LOG_TAG, "%s", ret == BT_ERROR_NONE ? "bt_gatt_set_value (0x02) success*" : "bt_gatt_set_value(0x02) failed" + ret); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "bt_gatt_set_value(0x02) failed : %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "bt_gatt_set_value (0x02) success"); } //3) write value: ret = bt_gatt_client_write_value(desc, __bt_gatt_client_write_complete_cb, NULL); if (ret == BT_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "Successfully set write- 0x02"); else dlog_print(DLOG_INFO, LOG_TAG, "Failed to set write- 0x02"); //fire command-> set then write //0)get fresh udid 1) set type for char for write. 2) set value-command 3) call back //0) set fresh udid for control_point also take chr bt_gatt_h control_point = NULL; ret = bt_gatt_service_get_characteristic(svc, chr_uuid, &control_point); if (ret == BT_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "Success - control point"); //1) set type to chr. ret = bt_gatt_characteristic_set_write_type(control_point, BT_GATT_WRITE_TYPE_WRITE); //BT_DATA_TYPE_UINT8 if (ret == BT_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "Successfully set write type"); else dlog_print(DLOG_INFO, LOG_TAG, "Failed to set write type"); //2) set command +++ ret = __bt_gatt_client_set_value("uint8", "0x2b0x2b0x2b0x0D", control_point); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "bt_gatt_set_value failed (+++) : %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "bt_gatt_set_value(+++) success"); } //3) write callback ret = bt_gatt_client_write_value(control_point, __bt_gatt_client_write_complete_cb, NULL); if (ret == BT_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "Successfully set write"); else dlog_print(DLOG_INFO, LOG_TAG, "Failed to set write"); //4) Read value: ret = bt_gatt_client_read_value(control_point, __bt_gatt_client_read_complete_cb, NULL); dlog_print(DLOG_INFO, LOG_TAG, "%s", ret == BT_ERROR_NONE ? "bt_att_client_read_value-(+++) Successfully*" : "bt_gatt_client_read_value-(+++) failed*"); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_read_value-(+++) failed: %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_read_value-(+++) Successfully"); } //Register a callback function to be invoked when the characteristic value changes on the remote device: ret = bt_gatt_client_set_characteristic_value_changed_cb(chr, __bt_gatt_client_value_changed_cb, NULL); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "bt_gatt_client_set_characteristic_value_changed_cb failed: %d", ret); //return; } else { dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_set_characteristic_value_changed_cb Success", ret); } //set value- +++ command ret = __bt_gatt_client_set_value("uint8", "0x2b0x2b0x2b0x0D", chr); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "bt_gatt_set_value failed (+++) : %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "bt_gatt_set_value(+++) success"); } //write value (+++) //fail to write ret = bt_gatt_client_write_value(chr, __bt_gatt_client_write_complete_cb, NULL); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "bt_gatt_client_write_value(+++) failed : %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_write_value(+++) Successful"); } //read value after set value of descriptor // got error bt_gatt_client_read_value-(+++) failed: -115 ret = bt_gatt_client_read_value(desc, __bt_gatt_client_read_complete_cb, NULL); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG_GATT, "bt_gatt_client_read_value (+++) failed : %d", ret); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "bt_gatt_client_read_value (+++) success : %d", ret); } //Disconnect remote address - GATT Temporary basel. ret = bt_gatt_disconnect(addr); dlog_print(DLOG_INFO, LOG_TAG, "%s", ret == BT_ERROR_NONE ? "Successfully disconnect" : "Fail to disconnect"); } else { dlog_print(DLOG_INFO, LOG_TAG_GATT, "fail to read services"); } } } //free(finalDname); //g_free(device_name); } //Format Device name: char* getFinalDeviceName(char* main, char* substring) { int i, j = 0, k = 0; //char str[100], key[20]; char str1[10][20]; for (i = 0; main[i] != '\0'; i++) { if (main[i] == ' ') { str1[k][j] = '\0'; k++; j = 0; } else { str1[k][j] = main[i]; j++; } } str1[k][j] = '\0'; /* Compares the string with given word */ for (i = 0; i < k + 1; i++) { if (strcmp(str1[i], substring) == 0) { for (j = i; j < k + 1; j++) strcpy(str1[j], str1[j + 1]); k--; } } for (i = 0; i < k + 1; i++) { printf("\nRemoveString1 %s ", str1[i]); dlog_print(DLOG_INFO, LOG_TAG, "RemoveString1 %s ", str1[i]); } //last index like : BA-000231 //char* substr=removeSpaces(str1[k]); //dlog_print(DLOG_INFO, LOG_TAG, "Trim %s",substr); char finalStr[10]; memset(finalStr, '\0', sizeof(finalStr)); //to clear memory location. strncpy(finalStr, str1[k], 7); return finalStr; } /************************************************************************************************************ GATT ************************************************************************************************************/ /* Register for GATT connection callback */ void __bt_gatt_connection_state_changed_cb(int result, bool connected, const char *remote_address, void *user_data) { if (connected) { dlog_print(DLOG_INFO, LOG_TAG_GATT, "LE_connected"); dlog_print(DLOG_INFO, LOG_TAG_GATT, "Remote Address from GATT-CB %s", remote_address); } else dlog_print(DLOG_INFO, LOG_TAG_GATT, "LE_disconnected"); } //Discover the service, characteristics, and descriptors of the remote service: //to initiate the service characteristics discovery bool __bt_gatt_client_foreach_svc_cb(int total, int index, bt_gatt_h svc_handle, void *data) { int ret; char *uuid = NULL; bt_gatt_get_uuid(svc_handle, &uuid); dlog_print(DLOG_INFO, LOG_TAG, "[%d / %d] uuid : (%s)", index, total, uuid); g_free(uuid); ret = bt_gatt_service_foreach_characteristics(svc_handle, __bt_gatt_client_foreach_chr_cb, NULL); if (ret != BT_ERROR_NONE) { dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_foreach_characteristics is failed : %d", ret); } return true; } //to discover the characteristic : bool __bt_gatt_client_foreach_chr_cb(int total, int index, bt_gatt_h chr_handle, void *data) { int ret; char *uuid = NULL; bt_gatt_get_uuid(chr_handle, &uuid); dlog_print(DLOG_INFO, LOG_TAG, "\t[%d / %d] uuid : (%s)", index, total, uuid); g_free(uuid); ret = bt_gatt_characteristic_foreach_descriptors(chr_handle, __bt_gatt_client_foreach_desc_cb, NULL); if (ret != BT_ERROR_NONE) dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_characteristic_foreach_descriptors is failed : %d", ret); return true; } //to get the descriptor data bool __bt_gatt_client_foreach_desc_cb(int total, int index, bt_gatt_h desc_handle, void *data) { char *uuid = NULL; bt_gatt_get_uuid(desc_handle, &uuid); dlog_print(DLOG_INFO, LOG_TAG, "\t\t[%d / %d] uuid : (%s)", index, total, uuid); // g_free(uuid); return true; } void __bt_gatt_client_read_complete_cb(int result, bt_gatt_h gatt_handle, void *data) { char *uuid = NULL; bt_gatt_get_uuid(gatt_handle, &uuid); dlog_print(DLOG_INFO, LOG_TAG, "Read %s for uuid: (%s)", result == BT_ERROR_NONE ? "Success" : "Fail", uuid); g_free(uuid); if (result != BT_ERROR_NONE) return; return; } void __bt_gatt_client_write_complete_cb(int result, bt_gatt_h gatt_handle, void *data) { char *uuid = NULL; bt_gatt_get_uuid(gatt_handle, &uuid); dlog_print(DLOG_INFO, LOG_TAG, "Write %s for uuid: (%s)", result == BT_ERROR_NONE ? "Success" : "Fail", uuid); g_free(uuid); return; } int __bt_gatt_client_set_value(char *type, char *value, bt_gatt_h h) { int ret; int s_val; unsigned int u_val; char *buf; int len; if (strcasecmp(type, "int8") == 0) { s_val = atoi(value); buf = (char *) &s_val; len = 1; } else if (strcasecmp(type, "int16") == 0) { s_val = atoi(value); buf = (char *) &s_val; len = 2; } else if (strcasecmp(type, "int32") == 0) { s_val = atoi(value); buf = (char *) &s_val; len = 4; } else if (strcasecmp(type, "uint8") == 0) { u_val = strtoul(value, NULL, 10); buf = (char *) &u_val; len = 1; } else if (strcasecmp(type, "uint16") == 0) { u_val = strtoul(value, NULL, 10); buf = (char *) &u_val; len = 2; } else if (strcasecmp(type, "uint32") == 0) { u_val = strtoul(value, NULL, 10); buf = (char *) &u_val; len = 4; } else if (strcasecmp(type, "str") == 0) { buf = value; len = strlen(buf); } else return BT_ERROR_INVALID_PARAMETER; ret = bt_gatt_set_value(h, buf, len); if (ret != BT_ERROR_NONE) dlog_print(DLOG_ERROR, LOG_TAG, "bt_gatt_set_value failed : %d", ret); return ret; } void __bt_gatt_client_value_changed_cb(bt_gatt_h chr, char *value, int len, void *user_data) { char *uuid = NULL; int i; bt_gatt_get_uuid(chr, &uuid); dlog_print(DLOG_INFO, LOG_TAG, "Value changed for [%s]", uuid); dlog_print(DLOG_INFO, LOG_TAG, "len [%d]", len); for (i = 0; i < len; i++) dlog_print(DLOG_INFO, LOG_TAG, "value %u", value[i]); g_free(uuid); return; }
Regards,
Vrajesh.