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 a string from keyfob to dongle.

Other Parts Discussed in Thread: CC2540

Hi everyone,

I'm just starting studying the sample program and trying to send a string "Hello World" from my keyfob to the dongle by modifying the "SimpleBLEPeripheral.c". But I couldn't find a function to send a string, or say, I don't even know where I should insert that function? I know it should be very simple code and process but I spent the whole week studing the Software Developer's Guide and still can't figure it out?

Could anyone show me how to realize it please? I would appreciate it very much if you could help me to start up.

Many thanks,

Jack

  • Unfortunately there is no command to send a string as far as I'm aware. The current project implementations for BLE and BLE in general are not very friendly when it comes to sending more than a few bytes.

    To send a string you have to modify the size of the characteristic value that is being sent by the keyfob to a larger number of bytes (up to the max 18 or 19) from memory. If you are wanting to send more data than this you have to add code on both ends to break up the stream into packets and handle the re-assembly.

    This is what I have done to make a 2 way data link work - it took a fair amount of hair pulling

  • Hi Michael,

    Thanks so much for your reply.

    Actually I'm just starting up programming the cc2540, what I want is just to send data from keyfob to USB dongle so that I could try to use it to advertise other contents in the next step.

    I went through Software Developer's Guide and the sample application code i.e SimpleBLEPeripheral, etc. But I still have no idea how to realize this function.

    I did find some method in this forum like:

            "  attHandleValueInd_t indication;

                indication.handle = attr->handle;

                indication.len =len;

                VOID osal_memcpy( indication.value, &thermProfileIntervalValue, HTHERM_INTERVAL_LEN ) ;

                ret = GATT_Indication( thermConnHandle,&indication,FALSE,thermProfile_TaskID );  "

    But I have no idea how they know they need to use attHandleValueInd_t  to declare a variable, etc. I feel I have lack of one area of knowledge. If I didn't see the posts, I don't even know I should use attHandleValueInd_t to declare a variable and use GATT_Indication to send data.

    Though I followed the way they did, there're still errors in my code. Could you please let me know what material or code I should refer to, or could you please just tell me how I could realize to just send data, not necessarily a "String"?

    I would appreciate very much if you could provide me any suggestions for me to start up my programming. Thank you very much!!

    Jack

  • Hi Jack

    I was in the same position as you 2 months ago, it is a steep learning curve.

    Unfortunately there is no easy way other than to analyse the example code in depth and follow the communications process in code. The software developers guide is only a guide. I spent days reading code from SimpleBLECentral and SimpleBLEPeripheral to understand how it worked before I started trying to modify it. 

    I would start with understanding the GAP first and how connections are made, attribute discovery and then the GATT.

    Have you looked at the API Guide? - this tells you in more depth what each GATT API function does and summarizes all of the data structures, but reading code is better still.

    You should read the documentation further and understand what mechanisms are used to send data back and forward between the peripheral and central devices e.g. Read / Write / Notify / Indicate. Then look at the API and understand how these functions are achieved in code. 

    The API will tell you what type of variables each function is expecting. This will make the above code make more sense.

    As I found a detailed understanding of is required at some stage as your application deviates from the examples Unfortunately for you no one here can write the code for your application. 

  • Hi Michael,

    I appreciate your assistance and kindness very much. Thank you.

    You have provided lots of information to me, I'm going to study the API Guide now, and again analyse the code in depth, thanks your suggestions.

    Best wishes,

    Jack

  • Hi Michael,

    I've studied a lot about the code and API Guide, and now I've tried to modify the code in simpleBLEPeripheral.c, trying to send indication, but I've got a question here hope you could give me any suggestions:

    when i define attHandleValueInd_t Indication; I know there're three data fields in attHandleValueInd_t type, but I have no idea what the first data field handle should be, in thermometer.c, it is themometerMeas.handle = THERMOMETER_TEP_VALUE_POS; but I found nowhere define THERMOMETER_TEP_VALUE_POS.

    Could you please let me know what I should assign to the handle?

    Thank you very much!

    Jack

  • Have you tried to do:

    Ctrl + shift + f

    and search for "THERMOMETER_TEP_VALUE_POS."? This searches in all the files of the project.

  • Yes, but no found. Do you have any idea what value should be assigned to Indication.handle? Thanks.

    Jack

  • One model that works for me is to think of BLE characteristics as hardware registers that are remotely accessed via BLE.  The Central device reads and writes 'registers' in the Peripheral device. Each 'register' contains data of a particular type, 8-bit number, 16-bit number, string, etc; each register can be read-only, write-only or read/write.

    Have a look at Profiles\SimpleProfile\simpleGATTprofile.c and you can see where the 'registers' (characteristics in BLE-speak) are set up in the table simpleProfileAttrTbl[]. Most of the heavy lifting is done inside the TI BLE stack, callbacks in the application are invoked when the Central reads or writes the Peripheral's characteristics.

    The Central device can read and write characteristics in the Peripheral device by calling GATT_ReadCharValue() and GATT_WriteCharValue(). It looks like there are a number of GATT api's for reading and writing, depending on the type of data being accessed.

    I'm not familiar with the thermometer app, but I think indications are a method by which the Peripheral device can inform the Central device that one of its characteristics has changed (called Notifications in BLE-speak).

    Another simplification is Peripheral=Server and Central=Client; the Peripheral server is serving up characteristics to the Central Client.

    Hope this helps a bit.

    Richard

  • 
    
    This is the way the notify code works in the SimpleBLEPeripheral (code from simpleGATTprofile.c):
    Firstly the code searches for the attribute in the attribute table (pValue contains a pointer to the attribute value).
    If it is found, the variable noti is constructed (simpleProfile_ReadAttrCB function reads the characteristic value into noti). 
    The noti.handle value is loaded from the simpleProfileAttrTbl which contains all of the handles for each characteristic.
    I would assume Indications can use the same code to build up the attHandleValueInd_t variable.
    
    
    
    
      pAttr = GATTServApp_FindAttr( simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ), pValue );
    if ( pAttr != NULL )
    {
    attHandleValueNoti_t noti;

    // If the attribute value is longer than (ATT_MTU - 3) octets, then
    // only the first (ATT_MTU - 3) octets of this attributes value can
    // be sent in a notification.
    if ( simpleProfile_ReadAttrCB( pItem->connHandle, pAttr, noti.value,
    &noti.len, 0, (ATT_MTU_SIZE-3) ) == SUCCESS )
    {
    noti.handle = pAttr->handle;

    if ( pItem->value & GATT_CLIENT_CFG_NOTIFY )
    {
    VOID GATT_Notification( pItem->connHandle, &noti, authenticated );
    }
    }
    }