BAS central doesn't connect to peripheral, bt_uuid_cmp() fails

Hello,

Im developing a custom BLE mouse plus receiver, where they both implement the BAS BT service to keep track of the mouse battery.

So far I got it to work using my mouse with the BAS peripheral code together with the BAS Central Sample, but if I copy the BAS Central Sample code into my receiver, the bt_bas_handles_assign(dm, &bas); function fails, because the bt_uuid_cmp(gatt_service->uuid, BT_UUID_BAS); inside of it (from bas_client.c) fails. It compares the UUID of the current GATT service and BT_UUID_BAS by subtracting the first from the second:

I modified bt_uuid_cmp() to print out the values:

Running the code I get:

My peripheral + my central gives different of UUID's, returns 3 and fails

My peripheral + BAS Central Sample has same UUID's, returns 0 and proceeds.

As you can see the UUID of my gatt_service changes in the two situations, how do I get it to be the same?

I don't understand how it is set in the first place.

Thanks

  • My peripheral + my central gives different of UUID's, returns 3 and fails

    This is because the discovery callback you got is not for BAS UUID discovery but instead it discovered BT_UUID_HIDS_VAL (0x1812 == 6162). You need to check why the discovery callback is called for HID even though you have registered the callback to be called only for BAS.

    Or it could be that bt_bas_handles_assign is working wrong and your attribute table is a bit different now and the function below is getting HID UUID now instead of BAS. If that is the case I would assume bt_gatt_dm_attr_service_val is designed wrong.

    struct bt_gatt_service_val *bt_gatt_dm_attr_service_val(
    	const struct bt_gatt_dm_attr *attr)
    {
    	if ((!bt_uuid_cmp(BT_UUID_GATT_PRIMARY, attr->uuid)) ||
    	    (!bt_uuid_cmp(BT_UUID_GATT_SECONDARY, attr->uuid))) {
    		return &((struct bt_gatt_service_val *)attr->uuid)[-1];
    	}
    	return NULL;
    }

  • You need to check why the discovery callback is called for HID even though you have registered the callback to be called only for BAS.

    This was the key, I discovered that I had set the same callbacks for HID and BAS, so I separated them:

    Now I can succesfully receive the BAS notiications!

    One last issues I have is that if I call bt_gatt_dm_start() on the BT_UUID_BAS first, the next call with BT_UUID_HIDS fails with EALREADY (socket already in use):

    and vice versa if I call HIDS first and BAS second.

    What I understand from this, and pardon possible imprecisions, is that a single BLE connection object can only be set to a single GATT service..? In that case I need a way to check the UUID of the GATT service I just connected to inside the following connected() BLE callback:

    I also think that I need two different scanning functions given that I want to use both HIDS and BAS together, where the difference would just be the target UUID.

    Am I on the right track?

    Thanks

  • StefanoN said:
    This was the key, I discovered that I had set the same callbacks for HID and BAS, so I separated them:

    Yes, that makes sense.

    StefanoN said:
    What I understand from this, and pardon possible imprecisions, is that a single BLE connection object can only be set to a single GATT service..? In that case I need a way to check the UUID of the GATT service I just connected to inside the following connected() BLE callback:

    No, you can use the same connection handle to set discoveries on different UUIDs but not at the same time. Best way to do this in my opinion is to start the discovery on one UUID (say on BAS first) and when you have the discovery complete callback, then start the discovery on the other (HIDS). I have done this before and had no issues  Just make sure that the callback handlers for both are different so that your application is not confused.

  • Calling bt_gatt_dm_start(conn, BT_UUID_BAS, &bas_discovery_cb, NULL); inside the HIDS_discovery_complete_cb() did the trick!

    Thanks a lot

Related