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.

CCS/LAUNCHXL-CC1352P: Passive communication between two modules

Part Number: LAUNCHXL-CC1352P
Other Parts Discussed in Thread: SHA-256

Tool/software: Code Composer Studio

Hi,

I want to make a system that communicate in passive mode. The emitter and receiver are both CC1352P1. Basically I want to send just a signal to the receiver (RF : 868MHz) when I put power on the emitter, when the receiver get the signal, it activate an output to HIGH in example.

But I want an unique connection between the two modules.

Like use AES 128 to pair them the first time and next they both save the paired key (in example press a pairing button on both modules). And maybe encrypt data with SHA-256 if possible. With which example can I start ?

I have read most of documentations but I don't know how to do it and there isn't enough examples to help me to understand.

Thanks,

Regards

  • An easy way of implementing this would be by using the TI 15.4 Stack example applications which provide a way of making a connection between 2 devices and it has built in security and it supports the 868MHz band
  • Thanks for the reply!

    So with this example, the connection is already crypted? I just need to make the pairing part?
  • In the TI 15.4 Examples pretty much everything is taken care for you, the only thing that you would have to do is transfer your own data which will be encrypted by default. The examples also take care of pairing by pressing a button on the board to allow devices to pair. You can read more about the examples and TI 15.4 Stack here dev.ti.com/.../

    There are 2 example applications, 1 is called Collector and another one is called Sensor. Multiple sensors can be paired to a collector at once and data can be transfered between collector and sensors. Sensors are also configured as sleepy low power devices so you wouldn't need to do any extra modifications if you want low power consumption
  • Ok go it!

    So if I understand :

    - The collector send data to search sensors ?
    - The sensor get the data and send to the collector a key ?

    When they are paired, does they have both a paired key ?

    Like if I remove power to both and them I power them, does they connect each other automatically?

    Thanks a lot!

  • By default these examples work with a pre-configured key so basically you would have to set the key in the source code but you should be able to use the APIs in the application to update the network key by sending a new one from the collector to the sensors.
    Also when pairing the sensor is the one that looks for a collector, if it finds a collector it tries to join the network
  • Ok!
    Is there any tutorial to use the API about sending the key ?
    The key is defined in config.h ?

    /*! Setting Default Key*/
    #define KEY_TABLE_DEFAULT_KEY {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,\
                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

  • Yes the pre configured key is defined in the config.h file as you pointed out.

    Unfortunately we do not have an example or tutorial on how you would go about sending and updating a key.

    I will give you some pointers on how you can do this:

    One way that you could do this would be to hijack the configuration request sent by the collector to the sensor. this request is sent to all sensors that join the network to configure their polling interval(how often they poll the collector to see if the collector has a message for them) and to configure the reporting interval(how often the sensor reports data back to the collector).
    You could modify the API "Collector_sendConfigRequest" to send a larger buffer that on top of the timing intervals it also contains the key new key.

    On the sensor side I recommend looking into the API "processConfigRequest" which as its name implies processes the incoming configuration message from the collector

    For now get familiar with those APIs and see if you can send the new key over the air. Once you have successfully sent the key to the sensor feel free to start another thread here in the forum if you need help on setting up the new key so the new key is used for encryption

  • Also, if you need a little bit more insight on the security and keys I recommend looking at this thread where I explain some of the concepts and usages of some of the security APIs in the software e2e.ti.com/.../730618
  • Thank for the help!

    So, I can send the key like this ? :

             

                /* Build the message */
                *pBuf++ = (uint8_t)Smsgs_cmdIds_configReq;
                *pBuf++ = Util_loUint16(frameControl);
                *pBuf++ = Util_hiUint16(frameControl);
                *pBuf++ = (uint8_t)KEY_TABLE_DEFAULT_KEY;
                *pBuf++ = Util_breakUint32(reportingInterval, 0);
                *pBuf++ = Util_breakUint32(reportingInterval, 1);
                *pBuf++ = Util_breakUint32(reportingInterval, 2);
                *pBuf++ = Util_breakUint32(reportingInterval, 3);
                *pBuf++ = Util_breakUint32(pollingInterval, 0);
                *pBuf++ = Util_breakUint32(pollingInterval, 1);
                *pBuf++ = Util_breakUint32(pollingInterval, 2);
                *pBuf = Util_breakUint32(pollingInterval, 3);

  • Just a small clarification, there is no need for you to send the KEY_TABLE_DEFAULT_KEY to the sensor device since this key is already configured in the code for both sensor and collector and it is used by default to encrypt all packets.

    If you want to update the sensor to use a new key that you generated in the collector side you would have to do it similarly to this

    //This is the new key for sensor
    uint8_t newKey[] = {0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0xbc, 0xde, 0xf0,
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
                uint8_t buffer[SMSGS_CONFIG_REQUEST_MSG_LENGTH + sizeof(newKey)]; //increase the size of the buffer to be able to fit the new key
                uint8_t *pBuf = buffer;
    
                /* Build the message */
                *pBuf++ = (uint8_t)Smsgs_cmdIds_configReq;
                *pBuf++ = Util_loUint16(frameControl);
                *pBuf++ = Util_hiUint16(frameControl);
                *pBuf++ = Util_breakUint32(reportingInterval, 0);
                *pBuf++ = Util_breakUint32(reportingInterval, 1);
                *pBuf++ = Util_breakUint32(reportingInterval, 2);
                *pBuf++ = Util_breakUint32(reportingInterval, 3);
                *pBuf++ = Util_breakUint32(pollingInterval, 0);
                *pBuf++ = Util_breakUint32(pollingInterval, 1);
                *pBuf++ = Util_breakUint32(pollingInterval, 2);
                *pBuf++ = Util_breakUint32(pollingInterval, 3);
                memcpy(pBbuf, newKey, sizeof(newKey));// copy the new key into the buffer that will be sent over the air

  • Ok got it!

    So for the sensor, I guess that I need to modify this function and add the receive PairingKey from the collector ?

    static void processConfigRequest(ApiMac_mcpsDataInd_t *pDataInd)

    and add like this :

        /* Make sure the message is the correct size */
        if(pDataInd->msdu.len == SMSGS_CONFIG_REQUEST_MSG_LENGTH)
        {
            uint8_t *pBuf = pDataInd->msdu.p;
            uint16_t frameControl;
            uint32_t reportingInterval;
            uint32_t pollingInterval;
            uint8_t PairingKey;

     

    /* Define the Pairing Key */
    uint8_t PairingKey[] = {0x66, 0x67};
    
    
    Collector_status_t Collector_sendConfigRequest(ApiMac_sAddr_t *pDstAddr,
                                                   uint16_t frameControl,
                                                   uint32_t reportingInterval,
                                                   uint32_t pollingInterval)
    {
        Collector_status_t status = Collector_status_invalid_state;
    
        /* Are we in the right state? */
        if(cllcState >= Cllc_states_started)
        {
            Llc_deviceListItem_t item;
    
            /* Is the device a known device? */
            if(Csf_getDevice(pDstAddr, &item))
            {
                uint8_t buffer[SMSGS_CONFIG_REQUEST_MSG_LENGTH + sizeof(PairingKey)];
                uint8_t *pBuf = buffer;
    
                /* Build the message */
                *pBuf++ = (uint8_t)Smsgs_cmdIds_configReq;
                *pBuf++ = Util_loUint16(frameControl);
                *pBuf++ = Util_hiUint16(frameControl);
                *pBuf++ = Util_breakUint32(reportingInterval, 0);
                *pBuf++ = Util_breakUint32(reportingInterval, 1);
                *pBuf++ = Util_breakUint32(reportingInterval, 2);
                *pBuf++ = Util_breakUint32(reportingInterval, 3);
                *pBuf++ = Util_breakUint32(pollingInterval, 0);
                *pBuf++ = Util_breakUint32(pollingInterval, 1);
                *pBuf++ = Util_breakUint32(pollingInterval, 2);
                *pBuf = Util_breakUint32(pollingInterval, 3);
                memcpy(pBuf, PairingKey, sizeof(PairingKey));

  • yes you are correct.

    Also, there is an error in your code, you are missing a "++", the second to last line should be:

    *pBuf++ = Util_breakUint32(pollingInterval, 3);
  • I think it is something like that but Util_parseUint16 would be Util_uint16toa ? but I don't know how to use it?

    uint16_t PairingKey;

            /* Parse the message */
            configSettings.cmdId = (Smsgs_cmdIds_t)*pBuf++;
            frameControl = Util_parseUint16(pBuf);
            pBuf += 2;
            reportingInterval = Util_parseUint32(pBuf);
            pBuf += 4;
            pollingInterval = Util_parseUint32(pBuf);
            pBuf += 4;
            PairingKey = Util_parseUint16(pBuf);
    
            printf("%c\n", PairingKey);

    Thanks!