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

ble mesh 5.0 couldn't send 255 bytes of data from client to server

Hi there,

For my POC test, I need to send a max 255 bytes payload data from a client to one or many servers. I use two nrf52832 DK boards, BLE sdk 17.0 and  BLE mesh 5.0 light_switch example project on SES. both client and server boards are provisioned via nrf Mesh phone app. configured both to publish to ALL and subscribe to the same group.

For my test, I modified the generic onoff model by add an opcode and a separate function in server side to print out the received data. Here are the brief changes;

/** Generic On Off model message opcodes. */

typedef enum

{

    GENERIC_ONOFF_OPCODE_SET = 0x8202,

    GENERIC_ONOFF_OPCODE_SET_UNACKNOWLEDGED = 0x8203,

    GENERIC_ONOFF_OPCODE_GET = 0x8201,

    GENERIC_ONOFF_OPCODE_STATUS = 0x8204,

    OPCODE_SEND_TEST_DATA = 0x8205                   // added this opcode

} generic_onoff_opcode_t; 

// test packet payload length

#define TEST_PAYLOAD_LENGTH   100          // works with 50 or less? 

/** Message format for the generic_onoff Set message. */

typedef struct __attribute((packed))

{

    uint8_t pktPayload[TEST_PAYLOAD_LENGTH];                 // added this 

    uint8_t on_off;                                         /**< State to set, must have it */

    uint8_t tid;                                            /**< Transaction number for application */

    uint8_t transition_time;                                /**< Encoded transition time value */

    uint8_t delay;                                          /**< Encoded message execution delay in 5 millisecond steps */

} generic_onoff_set_msg_pkt_t;

// in generic_onoff_client.c  I use btn3 to trigger send testData[ ] to server

uint32_t generic_onoff_client_set_unack(generic_onoff_client_t * p_client, const generic_onoff_set_params_t * p_params,
                                                                             const model_transition_t * p_transition, uint8_t repeats)
{
          uint8_t testData[TEST_PAYLOAD_LENGTH];          // add testData
          for (uint8_t i = 0; i < sizeof(testData); i++)
                         testData[i] = 0x01+i;


         if (p_client == NULL || p_params == NULL)
         {
                 return NRF_ERROR_NULL;
          }

          if (p_transition != NULL && (p_transition->transition_time_ms > TRANSITION_TIME_MAX_MS ||
                                p_transition->delay_ms > DELAY_TIME_MAX_MS))
          {
                  return NRF_ERROR_INVALID_PARAM;
          }

           generic_onoff_set_msg_pkt_t msg;
           uint8_t server_msg_length = message_set_packet_create(&msg, p_params, p_transition); 

          memcpy(&msg.pktPayload, testData, sizeof(testData));        // add this
         server_msg_length = TEST_PAYLOAD_LENGTH; 

         message_create(p_client, OPCODE_SEND_TEST_DATA /*GENERIC_ONOFF_OPCODE_SET_UNACKNOWLEDGED*/,
                                                 (const uint8_t *) &msg, server_msg_length, &p_client->access_message.message);

           uint32_t status = NRF_SUCCESS;
           repeats++;
          while (repeats-- > 0 && status == NRF_SUCCESS)
          {
                  status = access_model_publish(p_client->model_handle, &p_client->access_message.message);
           }
         return status;

}

// in generic_onoff_server.c   added this function

static void handle_send_status(access_model_handle_t model_handle, const access_message_rx_t * p_rx_msg, void * p_args)
{
         for(uint8_t i = 0; i< TEST_PAYLOAD_LENGTH; i++)
         {
                     __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "\n p_data: %X ", *((uint8_t *)((p_rx_msg->p_data)+i)));
                     nrf_delay_ms(1); // add delay, otherwise only print  out 32
          }
}

static const access_opcode_handler_t m_opcode_handlers[] =
{
{ACCESS_OPCODE_SIG(GENERIC_ONOFF_OPCODE_SET), handle_set},
{ACCESS_OPCODE_SIG(GENERIC_ONOFF_OPCODE_SET_UNACKNOWLEDGED), handle_set},
{ACCESS_OPCODE_SIG(GENERIC_ONOFF_OPCODE_GET), handle_get},
{ACCESS_OPCODE_SIG(OPCODE_SEND_TEST_DATA), handle_send_status},    //add this
};

There are some issues I found during my test and hope can get answers.

1. I can only send about 50 bytes from client to server, more than that on server side will get nothing,  I digged in and found in transport.c, the function  trs_seg_packet_in() is call correctly but will not call  upper_transport_packet_in() for some reason.  In nrf_mesh_define.h  there is a define NRF_MESH_SEG_PAYLOAD_SIZE_MAX (380), so the client should allow to send max 380 bytes. How can I test this out?

 2. In client main I use button3&4 to call generic_onoff_client_set_unack() to send testData,  if more than 9 bytes, will get “client cannot send” but actually the testData is sent out and print out correctly at server side as long as the length not greater than 50.

 3. I use button1&2 to send reliable message but always get “acknowledged transfer timeout” even though the testdata is sent and received correctly.

Thanks for your support in advance

Helen

  • Hi Helen, 

    The trs_seg_packet_in() will call upper_transport_packet_in() when all the segments of the message has been received. 
    The Bluetooth Mesh protocol is not really designed for sending large amount of data at once. When the payload is above 11bytes it will be split into segments. Transmitting segment would require ACK on the transport layer. And it would cause more traffic to the network (if the ACK message is missing, the whole segments would need to be re-transferred) 

    However you should be able to send above 50 bytes. I would suggest to try debugging by using some log inside trs_seg_packet_in() to check what you receive. Please print the log on the sender side as well. 

    2. Please make sure you don't call generic_onoff_client_set_unack() multiple times before the packet is received on the server side. You can have only one segmented message transmitting at a time. 

    3. Could you check if you receive any ACK on the client ? If you set the publication address to the unicast address of the server do you see the same issue ? It's not recommended to use reliable message to the ALL node address. 

Related