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

Writing Values to Characteristics in the Image Transfer Demo

Hello, I've set up the image transfer app from Nordic Playground with the idea in mind to remove the Android App from the equation. I've picked through the Android app itself, and have found the characteristics advertised on the Nordic nrf52-DK necessary to capture images from an Arducam and transmit them over BLE as intended. 

public static final UUID IMAGE_TRANSFER_SERVICE_UUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca3e");
public static final UUID RX_CHAR_UUID       = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca3e");
public static final UUID TX_CHAR_UUID       = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca3e");
public static final UUID IMG_INFO_CHAR_UUID = UUID.fromString("6e400004-b5a3-f393-e0a9-e50e24dcca3e");

Above are the three UUID's that I have been writing to via the nrfConnect app. Using nRFConnect, I turned on notifications for UUID's 6e400003 and 6e400004. Then, according to the Android app, writing "0x01" to UUID 6e400002 should trigger a "StartSingleCapture". This is confirmed to work on the nRFConnect app, and I can see the picture data being transferred over.

However, when using the ubuntu tool Bluetoothctl, it seems like writing to the UUID 6e400002 does not trigger a notification on neither of the UUID's 6e400003 and 6e400004. According to a bluetooth sniffer, I am sending the data over, I'm just not getting a response from the Nordic board. Clearly this could be due to a variety of issues, but I wanted to reach out and ask if anyone on the Nordic team has had experience writing values to the nrf52DK using the bluetoothctl tool (version 5.50).

The goal of this experiment is to be able to trigger an image transfer from the stock Nordic image transfer code on the nrf52, and receive the notification data on the linux side sending the data, essentially sidestepping the Android app all together. 

If you need any more information, please reach out.

Parents
  • Hi Richard

    Did you make sure to enable notifications on the 6e400003 and 6e400004 characteristics when running your test on Ubuntu?

    Did you try to run the debugger on the nRF52 side to see if the its_data_handler is actually called when you send the command?

    I can't really see any particular reason why this shouldn't work on Ubuntu. As you have seen the command structure for the BLE service is quite simple. 

    Best regards
    Torbjørn

  • Update 4:02PM EST

    I've traced the disconnection error to the ble_its_img_info_send() function. It returns a value of 8, which according to the documentation denotes an NRF_ERROR_INVALID_STATE error.

    As previously mentioned, this only happens when sending the bits with Bluetoothctl, not with the nrfConnect app. I will continue to look into what could be causing it to get to a bad state.

  • Another Update:

    So I've determined that the Nordic board is running into a problem in ble_its_string_send(). The function sd_ble_gatts_hvx() seems to queue too many notifications when trying to send a file, and returns an NRF_ERROR_RESOURCES. 

    This gets the Nordic board stuck in a while loop in main.c at the very bottom, in the line

    "while(ret_code == NRF_SUCCESS)"

    right after ble_its_send_file_fragment function. After about 4 iterations of the resources error, the board times out and disconnects! So now the problem is trying to figure out why the notifications are getting queued but not taken out of the queue. I run into a problem here because I can't seem to find the inner workings of sd_ble_gatts_hvx().

    In the file ble_gatts.h, the function description seems to mention that we should try "waiting for a BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry". Any idea where to go from here?

  • Hi Richard

    richardcoffey said:
    Could it be possible that there is another layer of communication that the nRFConnect app performs with the Nordic board that we could be missing?

    nRF Connect should go through service discovery, and should respond to requests from the peripheral to update GAP parameters (connection parameters) and GATT parameters (MTU size, data length). These settings might differ when using Bluetoothctl, depending on what parameters they support, but I don't understand why that should lead to such a big difference in behavior. 

    richardcoffey said:
    Do you think you might be able to give me some insight into the ble_evt_t ID's that I am seeing? Specifically the events 80, 85, and 87? In the ble_evt_handler() function, all three of those ID's are not caught by the switch statement, but they seem to come up frequently.

    The ID's are grouped by which sub-module in the Bluetooth stack they originate from (such as GAP, GATT server and GATT client). The event ranges are defined in ble_ranges.h, and here you can see that events 80, 85 and 87 belong to the GATT server module (as this corresponds to event 0x50, 0x55 and 0x57 in hex). 

    The exact events are defined in header files specific to the sub module, such as ble_gap.h, ble_gattc.h and ble_gatts.h. 

    Looking at ble_gatts.h you can see that 0x50, 0x55 and 0x57 corresponds to the following events:

    BLE_GATTS_EVT_WRITE - a write was performed on one of your characteristics

    BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST - the client is requesting to start an MTU request procedure

    BLE_GATTS_EVT_HVN_TX_COMPLETE - one or more notifications have successfully been sent

    While it is true these events are not handled in the main file directly all of them should be processed by one of the other modules in your application, such as the BLE service implementations or the nrf_ble_gatt.c module, so I don't think these events help much in tracking down the issue. 

    richardcoffey said:

    So I've determined that the Nordic board is running into a problem in ble_its_string_send(). The function sd_ble_gatts_hvx() seems to queue too many notifications when trying to send a file, and returns an NRF_ERROR_RESOURCES. 

    This gets the Nordic board stuck in a while loop in main.c at the very bottom, in the line

    "while(ret_code == NRF_SUCCESS)"

    Getting the NRF_ERROR_RESOURCES error is normal and expected. They way to maximize throughput is to push data to the stack quickly, and hold back once this error is returned. When you get the BLE_GATTS_EVT_HVN_TX_COMPLETE in return from the SoftDevice this means more buffers are freed up and you can continue to send more data. 

    If you look at line 413 of ble_image_transfer_service.c you can see the handling of this event, and how it will continue uploading more data. 

    When you say it gets stuck in the while(ret_code == NRF_SUCCESS) check, are you sure it really gets stuck here?
    That should only happen if the ble_its_send_file_fragment(..) function keeps returning NRF_SUCCESS. 

    If you put some log output or toggle a pin after the while loop, will you not see the code reaching here?

    Best regards
    Torbjørn

  • Hi Tor,

    As I've experimented more with the image transfer, I can see that you are correct in your explanation that the Nordic board frequently returns NRF_ERROR_RESOURCES, and then recovers as it receives BLE_GATTS_EVT_HVN_TX_COMPLETE notifications.

    The descrepency in behaviors seem to stem from the fact that BLE_GATTS_EVT_HVN_TX_COMPLETE notifications are not being returned, therefore the buffers never get rewritten and the process times out.

    Where would you suggest we go from here? 

  • Update:

    So, I decided to try and connect the Nordic device to a laptop running the same version of Bluetoothctl. Once connected, I was able to send and receive all commands correctly, proving that Bluetoothctl is capable of communicating with the Image Transfer code on the Nordic Device.

    That tells me that my original problem is a problem confined to the Linux box that I'm trying to use Bluetoothctl on. I will continue to try and figure out what could be different on the Linux Box vs. my Laptop.

  • Hi 

    That is interesting. Are you able to compare the Bluetooth sniffer logs between the two implementations to see if you can spot the difference there?

    Best regards
    Torbjørn

Reply Children
  • I've taken some more snippets of the successful image transfer, and an unsuccessful image transfer, as well as the connection messages for both sides. Something interesting that I've noticed on the client that's having trouble, is that there seems to be a 

    Here the connection log on the working device

    And here is a successful start to an image transfer. A notification comes up through 6e400004 (handle 0x0012) and then the image transfer data begins streaming over 6e400003.

    Here is the device connection on the non-working device.

    And here is the unsuccessful image transfer on the non-working device. The image info notification propagates up through 6e400004, but nothing comes up through 6e400003, and the device times out. I can't see anything that explains the problems from this picture, other than the fact that the device that doesn't work isn't getting the notifications with the image data.

    Something else that I've noticed that is different between the two, is that the non-working device records this odd bluetooth event every ~15 seconds while idle, although the timing is inconsistent. The working device does not record this message while idle. This might not be related to the problem, but I figured that I would include it.

  • Hi 

    Thanks for the added logs. 

    I can't seem to find the LE Create Connection packet for the non working device, showing the very start of connection establishment. Do you have this also?

    Do you know what kind of Bluetooth hardware is used by the non working device?
    Is it some kind of Bluetooth dongle?

    Best regards
    Torbjørn

  • Hi Tor,

    I am using a Qualcomm QCA9377 chipset for the Bluetooth. We are looking to see if we can update the firmware.

    Additionally, the LE Create Connect packet can be seen in both of the log pictures above. Both return a "Success 0x00" status, and are then followed by a "LE Connection Complete" event where the information about the connection is delivered, such as MAC and Peer Address. 

Related