This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Send and receive a string via access layer

Hi Team

I studied the examples for Bluetooth 5 mesh but i didn't find an example to communicate through access leyer. Can you give us some example lines of code, how this can be done? I'm working with the light-switch demo at the moment.

Parents
  • Update: Sorry for the confusion. I have tried to find out what the reason is that the client is not provisioning correctly, but it seems the issue is more complicated than I thought. Instead of posting a solution which currently does not work & only works for an outdated Mesh SDK, I think it would be best for now to explain how messaging can work on a theoretical level with mesh in the access layer. Sorry for any confusion caused.

    You can most likely base mesh messaging off of the light switch example in the Mesh SDK v1.0.0. In the light switch client example main.c file:

    To make this simple, I will assume you only want to send a message from one node to all of the other nodes on the mesh network. In order to do this, we can use the simple_message model created by an application engineer at Nordic. You'll want to download the file & extract it to the models folder in the Mesh SDK v1.0.0. I would get rid of one of the folders, so that the path to the folders img, include, simple_message & src become MeshSDK/models/simple_message instead of MeshSDK/models/simple_message/simple_message You'll want to include the simple_message_client.c file in the Simple OnOff Model folder in SES. In addition, you'll want to include the header files located in the models/simple_message/include folder. See this tutorial for help.

    uint32_t status=0;
    uint8_t buffer[30];
    uint8_t length;
    uint16_t address;
    access_message_tx_t msg;
    length= SEGGER_RTT_Read(0,buffer, sizeof(buffer));
               if (length)
                {
                  msg.opcode.opcode =simple_message_OPCODE_SEND;
                  msg.opcode.company_id = 0x0059; // Nordic's company ID
          
                  msg.p_buffer = (const uint8_t *) &buffer[0];
                  msg.length =length;
                  address = 0xCAFE;
                  address_set(address);
                  SEGGER_RTT_printf(0,"Sending to group address 0x%04x\n", address);
                  status= access_model_publish(m_clients[0].model_handle, &msg);
    
                  if (status == NRF_ERROR_INVALID_STATE ||
                  status == NRF_ERROR_BUSY||status == NRF_ERROR_NO_MEM)
                   {
                     __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Cannot send. Device is busy.\n");
                      hal_led_blink_ms(LEDS_MASK, 50, 4);
                   }
                   else
                   {
                         ERROR_CHECK(status);
                   }
                }
    

    To send a message, you could have two instances of Segger RTT viewer open. The status variable is used later in the code to see if the device is busy & to check for any errors that might have occurred. Going through the code, you will then need a buffer to store the message you want to send from one node to another node. The next variable is the length of the input message & is updated once the SEGGER_RTT_Read() function reads the input from the RTT terminal. Next, you can declare an address, which in our case will be the broadcast address to all of the other mesh nodes.

    You will also need to declare a variable access_message_tx_t msg; of struct access_message_txt_t. This struct is defined in the access.h file. The next statement after the if block sets the 14-bit or 7-bit Bluetooth SIG defined opcode or 6-bit vendor specific opcode (see access.h). The simple_message_OPCODE_SEND is defined in the simple message model. Then, you want to set the company ID, which in this case is Nordic's company ID. The next line sets the pointer to the address where the message starts. I am assuming you start the message at the buffer index 0. You also need to define the length of the message. As mentioned previously, the address is set to the broadcast address for all of the mesh nodes.

    The address_set function is defined as:

        void address_set(uint16_t addr)
    {
       ERROR_CHECK(dsm_address_publish_add(addr, &m_central_handle));
       ERROR_CHECK(access_model_publish_address_set(m_server.model_handle, m_central_handle));
     }
    

    & checks for errors. Then, you can add a print command to make understand what is happening in the real time terminal & call the access_model_publish function (see access.c & access.h). This function publishes an access layer message to the publish address of the model, which in our case is the broadcast address to all of the nodes.

    Lastly, some checks are done to ensure that the device is not busy or one last error_check is done.

    Inside the message_server main.c file:

    Use the same code as above but make a few changes:

    In the access_model_publish() function, use this statement instead:

    status= access_model_publish(m_server.model_handle, &msg);
    

    That should hopefully be the main things to be able to broadcast a message from one node to every other node (regardless of whether the node is a client or a server). I have not tested this to make sure it works in the latest Mesh SDK, so there could be some errors. Hope that helps!

  • has anyone made this work and or willing to share a working example?

  • Sorry for the delayed response. What is currently not working for you in the above example?

Reply Children
Related