This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Sending files with BLE?

Other Parts Discussed in Thread: CC2540

Dear all,

I am playing with BLE CC2540.

I would need to implement a solution for file transfer over BLE (although I know BLE is not really designed for it, but I expect it to work fine where transfer time is not an issue).

If I am correct, there is not sample code for a file transfer, but I am not sure about the steps I need to do.

Should I:

1- create a new GATT profile (or modify an existing one as Simple Gatt profile) in order to have a characteristic that can handle a longer data size than 1? 

2- is it the case that the maximum user data transfer in a single transaction can be 80 bytes (so my characteristic will be 80)?

3- when I have a data size established for a characteristic... can I send less? let's assume I have 80 but only 50 bytes of data... do I need to add 30 bytes of zeros or just send the 50 good ones?

4- finally I guess I have to split my files in the characteristic size and send each chunk in a different transfer message, right?

Can please someone advise if there is some misunderstanding in my logic?

Thanks for your help.

Mik

  • Hi Mik,

    I am glad that you are playing around with our CC2540. It is good that you understand that BLE isn't really designed for larger data transfers, so for the questions:

    1) Easiest way for you is to modify the simpleGATT profile. look at Characteristic 5 which has the size of 5 bytes. That one you could increase up to 20 bytes.

    2) No, the maximum packet size to transfer from the application to the lower layers is 20 Bytes so that would be the maximum one to use. So four of these packets could be sent OTA with a notification (Totally 80 bytes).

    3) When you read, or notification is sent, the whole characteristic is sent so typically you would have to fill with zeroes (or anything else).

    4) Yes you are correct.

    You seem to have a good basic understanding for BLE, so don't hesitate, just dig in :)

    Br

  • Hello Mik and Nick,

    This is Jonathan Tate with BluetoothSmartApps.com (Our site is not up yet).   We can provide a set of CC2540 libraries as a limited time demo software that you can "try" before you buy.
     
    We have a valid, proprietary, 128-bit UUID BLE Profile that demonstrates file transfer as well as "Over-Air-Download" OAD update of the CC2540 FLASH.
    Ballpark pricing:
    - $1995 for generic file transfer library + integration support into your proprietary application
    - $1995 for OAD library + integration support.
    $2495 for both.
    We also have the file transfer with iPhone 4s available in February.
    Please send me an email to jhtate@gmail.com and I can forward you an FTP Download for the libraries later this week.
    Thanks
    Jonathan Tate
    jhtate@gmail.com
  • Is this the right place for marketing?

    Does anybody need a bike? I sell it for 200€ and you can attach a CC2540 to it.

    Come on. Be TI friends and/or make a wiki entry but do not pollute a single post.

  • If you have a solution to someone's problem already implemented I don't see why you should't post it if it's relevant...

    BlueRadios offers CC2540 modules that come with a BLE profile that supports serial data transfer, remote configuration, as well as over the air updates.  The profile has been tested and works with the iPhone 4S.  You can find more info at www.blueradios.com.

  • Sorry. Just trying to help. I will place info on the Wiki
  • Thanks! :)

    It's time for new people start completing the wiki. I'll try to do new wiki entries if next week I can return to BLE development.

    For example... is anybody interested in developing a BLE PAM module for Linux? :) We can open a new thread if it results interesting.

  • Kazola and others,

    just to be sure: are you talking about this wiki?

    http://processors.wiki.ti.com/index.php/Category:BluetoothLE


    or am I am missing something?

  • Yeah, you are right.

    Let's make this thing grow up :)


  • Hello again everyone,

    I still cannot succeed to get the file transfer implementation working.
    But there are some _basics_ that I need to understand better I presume.

    The scenario is to use SimpleBLEPeripheral.c sample, then when pressing key 1 in the keyfob it will send a single number, while when pressing key 2 it will send an array (which in future will be a portion of the data of the file to transfer).

    I am modifying the GATT profile coming from simplekeys.* example code, and using the Characteristic 5 coming from SimpleGATTProfile.* sample.

    Between the others, I defined the following:

    // Simple Profile Characteristic 6 Properties
    static uint8 simpleProfileChar6Props = GATT_PROP_NOTIFY | GATT_PROP_READ | GATT_PROP_WRITE;

    // Characteristic 6 Value
    static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] =
    { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };

    // Simple Profile Characteristic 6 User Description
    static uint8 simpleProfileChar6UserDesp[20] = "Characteristic FILE\0";



    Now, on simplekeys.c-> SK_SetParameter()
    I have:
        case SK_KEY_ATTR:
          if ( len == sizeof ( uint8 ) )
          {
            skKeyPressed = *((uint8*)pValue);
           
             // See if Notification/Indication has been enabled
            sk_ProcessCharCfg( skConfig, &skKeyPressed, FALSE );               // ***1

          }
          else
          {
            ret = bleInvalidRange;
          }
          break;

       case SIMPLEPROFILE_CHAR6:
     
           VOID osal_memcpy( simpleProfileChar6, pValue, SIMPLEPROFILE_CHAR6_LEN );  // doesn't work     //***2
           [..]


    In ***1 it happens a Process Client Charateristic Configuration change,
    while in ***2 (coming from simpleGATTProfile.c-> SimpleProfile_SetParameter) there is just a memcpy.

    To me it seems like that there is no message sent after key 2 (for the array) is pressed.

    I maybe missing something very silly or fundamental...

    Does anyone have any idea?

    Also, IMHO, It would be great to see in the wiki an example for file transfer. If/when mine will work I can post it there..

    Thanks,
    Mik

  • For a better understanding,

    - if anyone is willing to have a look -, here comes my modified version of simplekeys.*

    Essentially it seems to me that when I send a single value is Ok, but when I send an array nothing happens...

    am I blind by the obvious?

    simpleHack.zip
  • Hi Michele,

    You have not defined any characteristic configuration for simpleProfileChar6 so you cant send it as notification, if that is what you wanted. Also test with using osal_memcpy instead of memcopy in your code. 

    Br

  • Hi Nick,

    thanks for your answer.

    I am still confused though: do you mean to add this block in the symplekeysAttrTbl ?

          // Characteristic configuration
          {
            { ATT_BT_UUID_SIZE, simpleProfilechar6UUID },
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,
            0,
            (uint8*) simpleProfileChar6
          },

    this one doesn't it make it working and also looking at simpleGATTprofile.c, in Characteristic 5, which has an array as well, it is not there.

    Could you please clarify?

    I agree about using osal_memcpy rather than memcpy, although in sample code devinfoservice.c they are using memcpy().

    Thanks,

    Mik

  • ...or...

    has this rather to do with the fact that for simple keys pressing, the function:

    sk_ProcessCharCfg() is called and that triggers GATT_Notification()?

    Does that mean that in simplaGATTProfile.c, a change on characteristic 5, which calls just osal_memcpy rather than simpleProfile_ProcessCharCfg(), will not be notified to the connected BLE unit?

  • Hi Mik,

    To use notifications you would need to add that piece of code, yes, but more like this:

          // Characteristic 6 configuration
    {
    { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    GATT_PERMIT_READ | GATT_PERMIT_WRITE,
    0,
    (uint8 *)simpleProfileChar6Config
    },
    You will need to define simpleProfileChar6Config as well as add other code similar as for
     "simpleProfileChar4" as notifications has been defined for that one (see SimpleProfile_SetParameter 
    and SimpleProfile_GetParameter for example).

    The simpleProfileChar5 do not have the notification option, that's part of the example.
     Please read the Software Developers Guide included in the stack documentation to understand the simpleProfile more.

    Br
  • Hi Nick,

    thanks again for your help.

    Yes, I did read the Software Developers Guide (twice, I need a third scan maybe:-), but I still didn't make it working as it should.

    The reason I was following simpleProfileChar5 rather than simpleProfileChar4, is because it is the only one using an array versus a single byte change.

    I tried to make the modifications you mentioned, but still I don't get anything out when pressing the second key.

    Something is not yet quite clear to me is if In SK_SetParameter() I need to call sk_ProcessCharCfg(...). Do I or do I not? It doesn't work either case, so maybe something else is wrong.

    I'll keep on reading documentation and example, hope to see the light!

    In the meanwhile I attach the hacked simplekeys.* code, just in case you or someone else have a clear idea of what I am making wrong.

    Thanks for your help.

    Mik6204.hack_simplekeys.zip.zip

  • Hi Nick,

    I'm trying to implement the same thing as Mik but after I write once using GATT_WriteLongCharValue() the program hangs up. What could be the reason?

    I'm using Simple Profile Char5 (with 5 bytes frame size). Although I have not added any notification properties to that profile. Please reply asap. Thanks.

  • Hi Akshat,

    GATT_WriteLongCharValue()  expect an response for each packet as stated in the TI BLE Vendor Specific HCI Guide,

    This sub-procedure is complete when either ATT_PrepareWriteRsp (with bleTimeout status),
    ATT_ExecuteWriteRsp (with SUCCESS or bleTimeout status), or ATT_ErrorRsp (with SUCCESS
    status) is received by the calling application task.
    Could you check this with a sniffer to make sure of this.
    Br

     

  • Hi Nick,

    Sorry forgot to mention that but it is receiving a ATT_ExecuteWriteRsp (not sure if status is SUCCESS or bleTimeout) but it still hangs up. I checked it using the LCD.

  • GATT_WriteLongCharValue() will break up you data into 19 byte packets and set them to the peripheral. This will trigger your write call back if you have set up the attribute table properly. The only difference is that the packets (aside from the first packet) will have an offset. In the examples provided by TI, an offset will cause the write callback to reply with an error. Remove that code

  • Now I need help.

    I can handle GATT_writeLongCharValue with my peripheral by adding the offset to my characteristic pointer and allocating space. 

    How do I handle GATT_ReadLongCharValue???

    This command never triggers my Read callback.  I saw  say that I should breaking my data up into multiple characteristics, but that's impractical. Reading the handle of user descriptions (GATT_CHAR_USER_DESC_UUID) will return data greater than 19 bytes without issue. This means there is some way for the chip/stack to handle blob reads/writes for the values themselves. without an app having to request information from multiple UUIDs or handles. 

    I may be using the word "blob" here incorrectly. I am very new to data transmission.