Data file transfer over BLE from nRF52832 device to iOS/Android device

I'm currently working with the nRF52832 and NCS V2.2.0, and in my application, I store a log file of activity on the nRF52 device, and when someone connects to it with an iOS or Android device, I want to be able to send that log file to them in JSON format.

My data is all stored in a struct, and Nordic have API's to convert it into the JSON format I want, but I'm just trying to home in on the easiest and quickest (in terms of development, not necessarily transfer speed) for getting a file that will be < 50kB across the BLE connection.

We originally looked at using SMP, and storing the log file in littlefs on the nRF52, but the flash memory overheads of littlefs were too high for the memory space we have available (< 20kB).

I've looked at a few of the examples Nordic has put together for NCS, namely the peripheral/client UART and throughput examples.  I think I can probably butcher both of these to achieve what I want, but I'm not sure of the compatibility of these with my iOS/Android device, so don't want to go down a path that ultimately won't get me where I want to be.

The other option I've considered is to just set up a custom service on both the client and server and just send/notify chunks of data that way and get the client to reconstruct the file.

Has anyone done something like this and willing to share how they went about it?

Cheers,

Mike

Parents
  • Hi Mike

    In order for indications to work the client side need to enable indications by writing to CCCD, how are you doing that on your end, as this only seems to be snippets from the peripheral side.

    In general it's enough to set the indicate bit and a writable CCCD for the characteristic in question. My colleague Edvin explains it very thoroughly in this ticket.

    Best regards,

    Simon

  • Hi Simon,

    I'm using the nRF Connect App on my phone and/or the nRF Connect for Desktop with another nRF52-DK as my Central, and I just have to press a button on either of those to enable the indications.  That part seems to work, as I have a callback function that gets called when the CCCD is changed, and that is informing me that indications has been enabled by the client (I check for BT_GATT_CCC_INDICATE)

    The issue is occuring when I actually try and write new data to the characteristic that the client has subscribed to for indications.  I think its because I'm not calling the correct API.

    With notifications, I call bt_gatt_notify_cb(conn, &params) and things seem to work.  With indications, I have been calling bt_gatt_indicate(conn, &params), and its at this point that things fall over.

    So, its the part of the process where I am trying to update the characteristic value after indications have been enabled that things aren't working.

    Regards,

    Mike

  • Hi Mike, 

    Simon is away, so I tried to debug using your code snippets.

    I used your code snippet to send an indication and see that I am getting -128 error (ENOTCONN 128). Saying that the indication cannot be sent due to lack of connected peer looking for this indication. I enabled the indications correctly but seems like there is some issue here. I was not able to debug this further but hoping to get to the bottom of this on Monday. Is this the same issue you are seeing or are you seeing some other behavior when you say that it is not working?

    If you are seeing a crash or hardfault, then I do not have the same setup or behavior as yours.

  • Hi Susheel,

    My issue is a hard fault that I think it related to how I am setting up the bt_gatt_indicate_params for the bt_gatt_indicate API call.

    Specifically, I don’t think I fully understand how to correctly set the .attr and/or .uuid values.

    if you could give me some assistance with that, I suspect I’ll be able to get it working.

    Cheers,

    Mike

  • Two things,

    1. I do not think you need to set the UUID here  params.uuid = BT_UUID_REMOTE_BUTTON_CHRC;for indication as you are giving the attr details here.
    2. If you are getting a hardfault with the same code snippet that you provided then I think it is not the issue of params initialization but I think it is the issue of the context in which you are calling this. I did not get the hardfault for the exact same code snippet you have.

    I do not see anything wrong in the code snippet for initializing bt_gatt_indicate_params other than params.len= sizeof(data) can be set wrong. What value does this translate to on your end? 

Reply
  • Two things,

    1. I do not think you need to set the UUID here  params.uuid = BT_UUID_REMOTE_BUTTON_CHRC;for indication as you are giving the attr details here.
    2. If you are getting a hardfault with the same code snippet that you provided then I think it is not the issue of params initialization but I think it is the issue of the context in which you are calling this. I did not get the hardfault for the exact same code snippet you have.

    I do not see anything wrong in the code snippet for initializing bt_gatt_indicate_params other than params.len= sizeof(data) can be set wrong. What value does this translate to on your end? 

Children
  • The hard fault issue was because I had set:

    struct bt_gatt_notify_params params = {0};

    This needs to be static.  Otherwise when the .destroy function goes to get called, the pointer to it no longer exists and it goes off to some random point in memory.

    But there was also an issue with the way I defined the .len parameter as well.  I've corrected that as well, so now I pass the actual length, rather than trying to calculate it via sizeof(data)

    Cheers,

    Mike

Related