Languages

Menu
Sites
Language
Tizen BLE Application, Descriptor write failed

Hello,

I need to develop a BLE Tizen Application, which will create a bond and write the Enable notification to Descriptor.

Tizen Application verson 2.3.1 building on Samsung Gear S3 Classic.

The Remote Device is Health Custom characteristic patch BLE device and It has two characteristic CHAR_NOTIFY and CHAR_WRITE and requires Encrypted channel for Writing using descriptor.

Using CHAR_NOTIFY characteristic , I have to get descriptor, on that descriptor, I have to perform read and write.

even I got the descriptor, read opearation is successful 

    ret = bt_gatt_client_read_value(desc, __bt_gatt_client_read_complete_cb, NULL);  by this method,

But when I am going to write on that descriptor ,It got failed. "Error :: Write failed -1"

ret = bt_gatt_client_write_value(desc, __write_completed_cb, NULL); by this Method
 
where desc is a descriptor achieved from get_characteristic.

below is code snippet :

#define CHAR_NOTIFY "00003a54-4f40-4c51-ad31-c410f4e12c04"
#define CHAR_WRITE "0000038b-4f40-4c51-ad31-c410f4e12c04"
#define CHAR_NOTIFYCCD "00002902-0000-1000-8000-00805f9b34fb"
#define SERVICE_UUID "0000f72b-4f40-4c51-ad31-c410f4e12c04"
 
ret = bt_initialize();
if (ret != BT_ERROR_NONE) {
dlog_print(DLOG_INFO, LOG_TAG, "BT init failed.");
}
else {
dlog_print(DLOG_INFO, LOG_TAG, "BT init succeed.");
}
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.");
}
 
 
void __bt_adapter_le_scan_result_cb(int result,bt_adapter_le_device_scan_result_info_s *info, void *user_data)
{
bt_adapter_le_packet_type_e pkt_type = BT_ADAPTER_LE_PACKET_ADVERTISING;
sprintf(str, "Device scanning");
if (info == NULL)
{
dlog_print(DLOG_INFO, LOG_TAG, "No discovery_info!");
return;
}
else
{
dlog_print(DLOG_INFO, LOG_TAG, "some info found for patch %s",info->remote_address);
}
dlog_print(DLOG_INFO, LOG_TAG, "Got our device");
bt_adapter_le_stop_scan();
ret = bt_gatt_set_connection_state_changed_cb(_bt_gatt_connection_state_changed_cb, NULL);
if (ret != BT_ERROR_NONE)
{
dlog_print(DLOG_ERROR, LOG_TAG,"[__bt_gatt_connection_state_changed_cb] Failed.");
}
else
{
dlog_print(DLOG_ERROR, LOG_TAG, "Callback registered. %d ", ret);
}
ret = bt_device_destroy_bond(info->remote_address);
if (ret != BT_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_destroy_bond] failed. %d",ret);
        return;
    } else {
        dlog_print(DLOG_INFO, LOG_TAG, "[bt_device_destroy_bond] succeeded. bt_device_destroy_bond callback will be called.");
    }
ret = bt_device_set_bond_created_cb(device_bond_created_cb, info->remote_address);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_set_bond_created_cb] failed. %d",ret);
 
    return;
}
ret = bt_gatt_connect(info->remote_address, true);
    if (ret != BT_ERROR_NONE)
    {
    dlog_print(DLOG_INFO, LOG_TAG, "Failed to connect LE device.", ret);
    } else {
    dlog_print(DLOG_INFO, LOG_TAG, "Connected to our LE device.%s",info->remote_address);
    ret = bt_device_create_bond(info->remote_address);
    if (ret != BT_ERROR_NONE) {
        dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_create_bond] failed.");
         return;
    } else {
   dlog_print(DLOG_INFO, LOG_TAG, "[bt_device_create_bond] succeeded. device_bond_created_cb callback will be called.");
    }
    }
 
void device_bond_created_cb(int result, bt_device_info_s *device_info, void *user_data)
{bt_gatt_h svc = NULL;
bt_gatt_h chr = NULL;
bt_gatt_h chr1 = NULL;
bt_gatt_h desc = NULL;
 
    if (result != BT_ERROR_NONE) {
        dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_bond_created_cb] failed. result(%d).", result);
        return;
    }
    dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_bond_created_cb] success. result(%d).", result);
    ret=bt_device_set_authorization_changed_cb(__bt_device_authorization_changed_cb,device_info->remote_address);
            if (ret != BT_ERROR_NONE)
                {
            dlog_print(DLOG_INFO, LOG_TAG, "callback is not registered");
                }
                else
                {
            dlog_print(DLOG_INFO, LOG_TAG, "athorization callback is  registered");
             }
        ret=bt_device_set_authorization(device_info->remote_address,BT_DEVICE_AUTHORIZED);
        if (ret != BT_ERROR_NONE)
        {
    dlog_print(DLOG_INFO, LOG_TAG, "device is not authorized %d",ret);
    dlog_print(DLOG_INFO, LOG_TAG, "device is not authorized remote address %s",device_info->remote_address);
        }
        else
        {
    dlog_print(DLOG_INFO, LOG_TAG, "device authorized");
     }
ret = bt_gatt_client_create(device_info->remote_address, &client);
if (ret == BT_ERROR_NONE)
{
dlog_print(DLOG_INFO, LOG_TAG, "Client created");
Evas_Object *label = elm_label_add(box);
evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(box,EVAS_HINT_FILL,EVAS_HINT_FILL);
elm_object_text_set(label, "Client Created");
elm_box_pack_end(box,label);
evas_object_show(label);
char *addr = NULL;
ret = bt_gatt_client_get_remote_address(client, &addr);
if (ret == BT_ERROR_NONE)
dlog_print(DLOG_INFO, LOG_TAG, "Success %s",addr);
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, "fail");
}
ret = bt_gatt_client_get_service(client, SERVICE_UUID, &svc);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_get_service failed: %d", ret);
    return;
}
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_get_service success: %d", ret);
 
ret = bt_gatt_service_get_characteristic(svc, CHAR_WRITE, &chr);
    if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_get_characteristic failed: %d", ret);
     return;
    }
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_get_characteristic success: %d", ret);
 
ret = bt_gatt_service_get_characteristic(svc, CHAR_NOTIFY, &chr1);
    if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_get_characteristic failed: %d", ret);
 
    return;
    }
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_get_characteristic success: %d", ret);
 
    ret = bt_gatt_client_set_characteristic_value_changed_cb(chr1, __bt_gatt_client_value_changed_cb,
    NULL);
    if (ret != BT_ERROR_NONE) {
        dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_set_characteristic_value_changed_cb failed: %d", ret);
 
        return;
    }
 
ret = bt_gatt_characteristic_get_descriptor(chr1, CHAR_NOTIFYCCD, &desc);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_characteristic_get_descriptor failed: %d", ret);
 
    return;
}
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_characteristic_get_descriptor success: %d", ret);
 
 
 
    ret = bt_gatt_client_read_value(desc, __bt_gatt_client_read_complete_cb, NULL);
    if (ret != BT_ERROR_NONE) {
        dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_read_value failed: %d", ret);
 
        return;
    }

 char *myArray = (char []) {0x01, 0x00 };

ret = bt_gatt_set_value(desc, myArray, 2);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_set_value failed: %d", ret);
 
    return;
}
else {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_set_value :");
 
}

 

ret = bt_gatt_client_write_value(desc, __write_completed_cb, NULL);
 
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_write_value failed: %d %s", ret, ret);
 
    return;
}
 
}

I followed all the steps provided in the following URL:

https://developer.tizen.org/development/guides/native-application/connectivity-and-wireless/bluetooth

Actually , I build an Android Application which will successfully create a bond and write successfully with descriptor.

Please help me out what I am missing?

Edited by: Bhagyashree Dhotre on 12 Sep, 2018

Responses

6 Replies
Yasin Ali

Hi,
 
You may try with sample app(Bluetooth, .... ) where functionality are active and to understand code flow/functionality.
Check if you added privileges appropriately. You may refactor your code to modularize whole code. It will help you to find specific
point of code where actual problem exists.

Hope it will help.

Thanks.

Bhagyashree Dhotre

Hii,What I have done is that

1) Initialize Bluetooth

ret = bt_initialize();

2)start scanning the Nordic health BLE device as follows

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.");}
 
3) When I got my BLE device ,then I do first destroy the bond and rebond again because our Nordic BLE device when restarts, if the device is bonded then it starts to throw connection. after destroy bond,and stops le_scan(), rebond again as follows
if (strcmp(info->remote_address, "58:EB:14:06:27:D6") == 0 )
{elm_object_text_set(label, "Our Device Found");}
bt_adapter_le_stop_scan();
ret = bt_device_destroy_bond(info->remote_address);
if (ret != BT_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_destroy_bond] failed. %d",ret);
return;}
ret = bt_device_set_bond_created_cb(device_bond_created_cb, info->remote_address);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_set_bond_created_cb] failed. %d",ret);
    return;}
 
4)Now gatt-connect and create a bond 
ret = bt_gatt_connect(info->remote_address, true);
if (ret != BT_ERROR_NONE)
{ dlog_print(DLOG_INFO, LOG_TAG, "Failed to connect LE device.", ret);}
else { dlog_print(DLOG_INFO, LOG_TAG, "Connected to our LE device.%s",info->remote_address);
 ret = bt_device_create_bond(info->remote_address);
 if (ret != BT_ERROR_NONE)
{  dlog_print(DLOG_ERROR, LOG_TAG, "[bt_device_create_bond] failed.");
 return;}
else {dlog_print(DLOG_INFO, LOG_TAG, "[bt_device_create_bond] succeeded. device_bond_created_cb callback will be called.");}
 
5) After bond creation, In bonded callback, I create  a client and get charachteristic and get descriptor and on that descriptor I have to enable Notification by writing {0x01,0x00}.
#define CHAR_NOTIFY "00003a54-4f40-4c51-ad31-c410f4e12c04"
#define CHAR_NOTIFYCCD "00002902-0000-1000-8000-00805f9b34fb"
#define SERVICE_UUID "0000f72b-4f40-4c51-ad31-c410f4e12c04"
ret = bt_gatt_client_create(device_info->remote_address, &client);
if (ret == BT_ERROR_NONE)
{dlog_print(DLOG_INFO, LOG_TAG, "Client created");}
ret = bt_gatt_client_get_service(client, SERVICE_UUID, &svc);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_get_service failed: %d", ret);
    return;}
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_get_service success: %d", ret);
  ret = bt_gatt_service_get_characteristic(svc, CHAR_NOTIFY, &chr1);
  if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_get_characteristic failed: %d", ret);
    return;}
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_get_characteristic success: %d", ret);
 ret = bt_gatt_characteristic_get_descriptor(chr1,CHAR_NOTIFYCCD, &desc);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_characteristic_get_descriptor failed: %d", ret);
    return;}
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_characteristic_get_descriptor success: %d", ret);

 6)Now after getting descriptor, I have to write it as follows.

char *myArray = (char []) {0x01, 0x00 };

 ret = bt_gatt_set_value(desc, myArray, 2);

if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_set_value failed: %d", ret);
   return;}
ret = bt_gatt_client_write_value(desc, __write_completed_cb, NULL);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_write_value failed: %d %s", ret, ret);
   return}
 
This is the process which I have done in Tizen Application, Here It gives us a error as "Write failed -1" and Bonding, paring ,reading with descriptor is working. only enable notification using descriptor failed.
First Thing , The process which I have mention above is it correct or  am I missing someting in the code.
beacuse using same characteristic and descriptor I am able to write it to Nordic Ble device using Android Application.
and one more thing using descriptor I can read the values of characteristic as {0,0} (which is disabled notifications) which I have to make it {1,0} (which is Enabled notifications), I am able to read from the patch device using descriptor then why write get failed. From our understanding, Our Nordic BLe device  provides security like, for reading i don't require secure encrypted channel and  for writing it requires encrypted channel. so is this the reason we are missing encryption or some callback function or method to make it encryption bonding. or other reason?
and Is BLE in tizen provides encrypted channel to write it and what i am missing in the code?
I have added privileges and features as follows
tizen.org/privilege/bluetooth
tizen.org/feature/network.bluetooth
tizen.org/feature/network.bluetooth.le
 
I hope that you got the question.
Yasin Ali

Hi,

As far as I know connected devices exchange keys needed for encrypted communication, but each connection has to be approved by the latest application user. You can also set authorization of other devices. Authorized devices are connected automatically without the latest user being asked for authorization.

So I think you may check for application level permission.
Also for Cryptographic Operations check this link: https://developer.tizen.org/ko/development/guides/native-application/security/cryptographic-operations?langredirect=1

Bhagyashree Dhotre

hii,

Please tell me, What will be the reason to get failed in writing descriptor to the remote device?

Can you please explain me the meaning of (each connection has to be approved by the latest application user.) in term of tizen settings or the device and how to do that?

I also have used set authorization API call for the remote device.

how to check application level permission? I think we do not need to cryptographic operations for encypted channel.

Yasin Ali

If remote device does not provide sufficient permission to write then write fail may occur.

Check this https://developer.tizen.org/development/guides/native-application/connectivity-and-wireless/bluetooth
for detail explnation about connection approval others.

Bhagyashree Dhotre

Hi,

Using Android Application same thing i.e. writing with descriptor to remote device is working fine.

But In tizen Application it failed. 

 https://developer.tizen.org/development/guides/native-application/connectivity-and-wireless/bluetooth

Using above link, I followed all the steps which I have mentioned in the second post.

ret = bt_gatt_client_get_service(client, svc_uuid, &svc);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_client_get_service failed: %d", ret);

    return;
}

ret = bt_gatt_service_get_characteristic(svc, chr_uuid, &chr);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_service_get_characteristic failed: %d", ret);

    return;
}

ret = bt_gatt_characteristic_get_descriptor(chr, desc_uuid, &desc);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_characteristic_get_descriptor failed: %d", ret);

    return;
}

ret = __bt_gatt_client_set_value("int32", "1234", desc);
if (ret != BT_ERROR_NONE) {
    dlog_print(DLOG_INFO, LOG_TAG, "bt_gatt_set_value failed: %d", ret);

    return;
}

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, "bt_gatt_client_write_value failed: %d", ret);

    return;
}

but in the  above code,

ret = __bt_gatt_client_set_value("int32", "1234", desc);

here , I want to set the array of char as 

char *myArray = (char []) {0x01, 0x00 }; like

  ret = bt_gatt_set_value(desc,myArray, sizeof(myArray));

so how do I set this array. I want ot write that array not a single number as "1234" beacause I think so inapropriate settings of this array will be the reason of write failed.

Can you please tell me how to set this array in the above method.

In the android source code , the array is being declared as follows

public static final byte[] ENABLE_NOTIFICATION_VALUE = {0x01, 0x00};

so what will be an array in the Tizen application?