This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Seeing incorrect Service UUID on write request

I have two devices, both nRF52840, one as Client, one as Server.  There are a few services defined with a few characteristics in each.  Two of the services have values like so:

  • Service A:
    • Base UUID: A0000000-6D69-6E64-8711-737469783443
    • Service UUID: A001
    • Something Characteristic UUID: A002
  • Service B:
    • Base UUID: D0000000-6D69-6E64-8711-737469783443
    • Service UUID: D001
    • Otherthing Characteristic UUID: D002

I attempt to send a BLE_GATT_OP_PREP_WRITE_REQ for the Something characteristic from the client to the server.  I see it arrive at the server, but I get an NRF_ERROR_INVALID_STATE error from sd_ble_gatts_rw_authorize_reply.  This implies that there might be no auth pending.  I set up a sniffer to see the request and I always see the same thing:

  1. I see the correct Handle, doesn't matter but it's 0x002f in my case
  2. I see the correct Characteristic UUID: A000A002-6D69-6E64-8711-737469783443
  3. I see an incorrect Service UUID: D000D001-6D69-6E64-8711-737469783443

I am pretty sure that this is why I get the NRF_ERROR_INVALID_STATE returned from sd_ble_gatts_rw_authorize_reply.  When I look at the sniffer during discovery (I guess?  I'm swimming a little deeper than I am comfortable here...) I see a Received Read By Type Response to a GATT Characteristic Declaration that contains my handle, 0x002f and also has the same incorrect Service UUID.  This made me think I was initializing the Something characteristic incorrectly, but when I look I see that in my activity add function I correctly have:

ble_uuid.type = p_something->uuid_type;
ble_uuid.uuid = 0xA002;

and looking at where I add the service UUID for Service A it looks correct to me:

// Add service UUID
ble_uuid128_t base_uuid = { 0x43, 0x34, 0x78, 0x69, 0x74, 0x73, 0x11, 0x87, 0x64, 0x6E, 0x69, 0x6D, 0x00, 0x00, 0x00, 0xA0 };
ret_code = sd_ble_uuid_vs_add(&base_uuid, &p_partner->uuid_type);

I also checked the initialization for Service B and the Otherthing characteristic, but they have the correct values as well - I didn't accidentally put the Service A or Something characteristic values in or anything like that.  So how can it be that somewhere the wrong service UUID gets assigned?  I tried moving the order of their initialization to see if there might be some other values confusing the matter, but I get the same result (with a different handle, obviously).  I don't mind tracking down my own bugs, so I'm more wondering what/where else I should check to see that I didn't somehow overwrite these values?

**EDIT** Digging a little deeper, I don't see this same mistake during discovery if I connect to the server via nRF Connect with my phone.  In this case I see the correct service UUID and characteristic UUID for the Something characteristic of Service A.  This made me think I had an error in my service client routine, but again I see that I pass the correct values during initialization. But it does have me thinking that the error is in my client code and not my server code.  Here is my service client initialization code in case it helps:

uint32_t ble_service_A_client_init(ble_service_A_client_t       *p_sac,
                                   ble_service_A_client_init_t  *p_sac_init)
{
    uint32_t      err_code;
    ble_uuid_t    service_A_uuid;
    ble_uuid128_t service_A_base_uuid = { 0x43, 0x34, 0x78, 0x69, 0x74, 0x73, 0x11, 0x87, 0x64, 0x6E, 0x69, 0x6D, 0x00, 0x00, 0x00, 0xA0 };

    VERIFY_PARAM_NOT_NULL(p_sac);
    VERIFY_PARAM_NOT_NULL(p_sac_init);
    VERIFY_PARAM_NOT_NULL(p_sac_init->evt_handler);

    p_sac->peer_partner_service_db.activity_handle  = BLE_GATT_HANDLE_INVALID;
    p_sac->conn_handle    = BLE_CONN_HANDLE_INVALID;
    p_sac->evt_handler    = p_sac_init->evt_handler;

    err_code = sd_ble_uuid_vs_add(&service_A_base_uuid, &p_sac->uuid_type);
    if (err_code != NRF_SUCCESS)
        return err_code;

    service_A_uuid.type = p_sac->uuid_type;
    service_A_uuid.uuid = BLE_UUID_service_A_uuid;

    return ble_db_discovery_evt_register(&service_A_uuid);
}

Parents Reply
  • I wrote it myself, but I'll have a look at the queued writes.  So you think that it's a contention (if that's the right word for it) issue? i.e., maybe SD is busy elsewhere so I should be waiting until it's free to perform the auth reply?

    EDIT: May I ask what leads you to think this?  While I would love it if the fix is so simple, it would be even more instructive to know how to think about the problems :-) Thanks!

Children
Related