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.

  • Hi Richard

    If you look at the ble_its_img_info_send(..) implementation it will return NRF_ERROR_INVALID_STATE either if you are not connected or if the notifications are not correctly set on that characteristic (6e400004). 

    I assume you are connected, so most likely the issue is that the notifications are not properly enabled. 

    One thing that can be confusing with BLE is the endianness of multi byte values. To enable notifications you should send 0x0001 to the CCCD, but when breaking this up into multi byte commands you often have to send {0x01, 0x00} rather than {0x00, 0x01} for the data to be properly interpreted. 

    Maybe you could show me the code you use to enable the notifications?
    There might be some issue here that prevents the notifications from being enabled properly. 

    Best regards
    Torbjørn

  • Hi Tor,

    On connection, it seems like the CCCD for UUID's 6e400003 and 6e400004 have already been set to {01, 00}. That being said, I did also set notifications on the UUID's themselves. I was not setting the notifications for the image transfer info UUID, but now that I am, I am getting a return value of 0, which means that it was a success!

    However, I am still seeing a disconnection after that request. I added some prints to display the event id in ble_evt_handler(), and I will also post the data from my bluetooth sniffer, as well as the program that I'm using the interface with the Nordic Device.

    Here is a snip of the Segger logs, where the image is clearly taken, with a successful return value. The "Current Event State" of 17 is of interest here, as this is the value that the p_ble_evt->header.evt_id has before entering into the switch statement in the ble_evt_handler() function before a time out.

    Here is a snippet of me writing to UUID 6e400002. The value of the attribute is already {0x01}, but writing another {0x01 00} causes it to disconnect.

    And then here are the logs of my bluetooth sniffer, in which you can see that I receive a notification from what looks like UUID 6e400004, but nothing from the UUID 6e400003, before receiving a connection timeout.

    I can confirm that both UUID's (6e400003/4) had notifications enabled. Hope this helps.

Reply
  • Hi Tor,

    On connection, it seems like the CCCD for UUID's 6e400003 and 6e400004 have already been set to {01, 00}. That being said, I did also set notifications on the UUID's themselves. I was not setting the notifications for the image transfer info UUID, but now that I am, I am getting a return value of 0, which means that it was a success!

    However, I am still seeing a disconnection after that request. I added some prints to display the event id in ble_evt_handler(), and I will also post the data from my bluetooth sniffer, as well as the program that I'm using the interface with the Nordic Device.

    Here is a snip of the Segger logs, where the image is clearly taken, with a successful return value. The "Current Event State" of 17 is of interest here, as this is the value that the p_ble_evt->header.evt_id has before entering into the switch statement in the ble_evt_handler() function before a time out.

    Here is a snippet of me writing to UUID 6e400002. The value of the attribute is already {0x01}, but writing another {0x01 00} causes it to disconnect.

    And then here are the logs of my bluetooth sniffer, in which you can see that I receive a notification from what looks like UUID 6e400004, but nothing from the UUID 6e400003, before receiving a connection timeout.

    I can confirm that both UUID's (6e400003/4) had notifications enabled. Hope this helps.

Children
  • I would also like to mention, that from a clean reboot, any request for information, whether it be a StartStream, StartSingleCapture, etc, leads to a "Connection Timeout".

    The data that I receive in the 3rd picture above from UUID 6e400004 of {0108180000} is the same data I get from that UUID when I successfully transfer data from the Nordic Device to the nRFConnect app. This is telling me that setting the notification for that UUID is working, and that it's specifically the reception of the data on UUID 6e400003 that is causing the issue.

  • Another comment, when the device gets stuck in a weird state while experimenting with the nRFConnect app, refreshing the services (with the refresh services button that appears to call "gatt.refresh()") seems to trigger the command that was queued up. Unfortunately I have no way of refreshing the services using my bluetoothctl tool on ubuntu.

  • Hi Richard

    The 17 event is simply the disconnected event, and the link has already disconnected once this event is forwarded. 
    You could try to print the disconnect reason inside the event, like this:

    NRF_LOG_INFO("Disconnected. Reason: %i", p_ble_evt->evt.gap_evt.params.disconnected.reason);

    Another thing you could try is to send write command rather than a write request from the bluetoothctl side. In theory both should work, but it is possible that the write response is somehow delayed when you start sending a lot of notifications on the 6e400003 characteristic, and that this will cause issues. 

    When you send a write command you are not dependent on getting an explicit ACK from the server side, and this is the intended behavior. 

    Do you know how to change from a write request to a write command through the bluetoothctl API's?

    Best regards
    Torbjørn

  • Hi Tor,

    I do not know how to send a write command in the Bluetoothctl, as far as I know all the commands are write requests. I will look into it.

    What stumps me is that the nordic nRFConnect app sends write requests, and that command flow works very well most of the time. Additionally, sending write requests to change things like resolutions and PHY layer configurations works on Bluetoothctl, and the notifications come back on UUID 6e400004 successfully.

    We are looking more into the C code to learn about the states.

    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? Considering that the Nordic device seems to become unresponsive when starting just image transfers, we are thinking that maybe it's blocking on a configuration setting that we failed to setup.

  • Hi Tor,

    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.

    It is a bit difficult to determine where these codes originate from, as the ble_evt_t  type contains a bunch of additional event types. The "header" value is where I'm getting the numbers 80,85, and 87. Perhaps knowing what those values denote will help me track down where the data is getting lost/not sent.

Related