Connecting to Custom Service/Characteristic of BLE peripheral with nRF52 acting as central.

I am currently connected to a BLE peripheral with the nRF52 acting as the central. I am able to scan using the device's name and connect. I created a custom file to handle the central functions including adding the custom UUID and starting the discovery. This done here

uint32_t ble_obd_c_init(ble_obd_c_t * p_obd_service_client, ble_obd_c_init_t * p_ble_obd_c_init)
{
    uint32_t      err_code;
    ble_uuid_t    obd_uuid;
    // TODO for V Link
    ble_uuid128_t obd_base_uuid = OBD_BASE_UUID;
    obd_uuid.uuid = BLE_UUID_OBD_SERVICE;
    obd_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN;

    VERIFY_PARAM_NOT_NULL(p_obd_service_client);
    VERIFY_PARAM_NOT_NULL(p_ble_obd_c_init);

    err_code = sd_ble_uuid_vs_add(&obd_base_uuid, &obd_uuid.type);
    VERIFY_SUCCESS(err_code);

    p_obd_service_client->conn_handle                    = BLE_CONN_HANDLE_INVALID;
    p_obd_service_client->evt_handler                    = p_ble_obd_c_init->evt_handler;
    p_obd_service_client->error_handler                  = p_ble_obd_c_init->error_handler;
    p_obd_service_client->obd_service_char.handle_value  = BLE_GATT_HANDLE_INVALID;
    p_obd_service_client->p_gatt_queue                   = p_ble_obd_c_init->p_gatt_queue;
    p_obd_service_client->uuid_type                      = BLE_UUID_TYPE_VENDOR_BEGIN;

    return ble_db_discovery_evt_register(&obd_uuid);
}

The discovery runs smoothly and finds the Service. The issue is that the characteristic is not there, so I am unable to read and write to the device. This is where I try and find the characteristic. The uuid type is returning as 4, but I thought there was only 0, 1, and 2 (I set it to 2, the BLE_UUID_TYPE_VENDOR_BEGIN).

void ble_obd_c_on_db_disc_evt(ble_obd_c_t * p_obd_service_client, ble_db_discovery_evt_t * p_evt)
{
    memset(&obd_c_evt,0,sizeof(ble_obd_c_evt_t));

    ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;

    // Check if the OBD was discovered.
    if (    (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
        &&  (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_OBD_SERVICE)
        &&  (p_evt->params.discovered_db.srv_uuid.type == p_obd_service_client->uuid_type))
    {
        for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
        {
            switch (p_chars[i].characteristic.uuid.uuid)
            {
                case BLE_UUID_OBD_CHARACTERISTIC:
                    // Found OBD characteristic inside the OBD Service.
                    p_obd_service_client->obd_service_char = p_chars[i].characteristic;
                    NRF_LOG_INFO("Discovered characteristic handle: %i", p_chars[i].characteristic.handle_value);
                    break;

                default:
                    break;
            }
        }
        if (p_obd_service_client->evt_handler != NULL)
        {
            obd_c_evt.conn_handle = p_evt->conn_handle;
            obd_c_evt.evt_type    = BLE_OBD_C_EVT_DISCOVERY_COMPLETE;
            p_obd_service_client->evt_handler(p_obd_service_client, &obd_c_evt);
        }
    }
}

These are my defines for the custom service/characteristics of the OBD device 

#define OBD_BASE_UUID {{0xF2, 0xC3, 0xF0, 0xAE, 0xA9, 0xFA, 0x15, 0x8C, 0x9D, 0x49, 0xAE, 0x73, 0x71, 0x0A, 0x81, 0xE7}}

#define BLE_UUID_OBD_SERVICE 0x0A71                   //< The UUID of the OBD Service. 
#define BLE_UUID_OBD_CHARACTERISTIC 0xD6C9  // < The UUID of the RX and TX Characteristic. 

I attached an image of the service/characteristic from nRF52 connect. 

I have another OBD device that uses 16 bit UUIDS and was able to do this easily, but since these use 128 bit UUIDs, I am running into some issues.

I have attached my wireshark capture from when I establish a connection, search for the service and then search for the characteristic for a working device and the non-working one. The LE Link Capture is working while the VLINK does not.

3225.VLINK Capture from connecting.pcapng5381.LE LINK Capture from connecting.pcapngVLINK to iOS Capture from connecting.pcapng

Parents Reply Children
  •   The peripheral is from an outside source, so I do not have any control over the code. Android and iOS devices are able to connect to and talk to this device. Just wondering if you see anything else I am possibly doing wrong?

    I have attached the wireshark capture from the working OBD Device too to the first message as well as an iOS app connecting to the OBD device.

  • I'm a bit confused on 3 files you attached. What are two files (3325.VLINK...and 5381.LE LINK). In addition to the capture with iOS, which one that you can receive or write to your peripheral device?

    Without knowing the peripheral firmware, it's quite challenging. I think using the capture with iOS, you should check how many characteristics that your peripheral device has and what is its service UUID. Having a quick look at it, seems it has 3 characteristics.

    You said your central code was able to discover the service. Check if its service UUID matches with that in the peripheral device. 

    I notice your central code is quite similar to ble_nus_c ble service, you can run that example using another nRF52 chip as a peripheral (running ble_nus_s ble service) to see how they behave.

  •  

    The three files are as follows:

    The LE Link file is me successfully connecting to and initializing one of the OBD II Devices.

    The VLINK file is me successfully connecting to but unsuccessfully finding the service/characteristic to read and write to.

    The VLINK iOS file is an iPhone OBD II app connecting to and initializing the OBD II Device that I am unable to with the nRF52. 

    I did a primary service discovery with the VLINK device in the nRF52 firmware and only found 4 Primary Services, 0x1800, 0x1801, 0x18F0, and 0x180A. It never found the Unknown Primary Service (e7810a71-73ae-499d-8c15-faa9aef0c3f2). This is the service with the read and write characteristic. 

    If I use the database discovery module to look for the service, I can find the service. The issue lies in that the p_evt->params.discovered_db.srv_uuid.type == p_obd_service_client->uuid_type) is not what I expect. The uuid type of the service is BLE_VENDOR_BEGIN but the discovered uuid type is 4 (which is undefined). Also, if I dive into the specifics of the service, the characteristic is not there.

Related