Reference to implement BLE-Mesh Large object (BLOB) transfer

Hi,

I need to transfer BLOB object upto 350kb through BLE-Mesh.

I saw the breakup of nCS that zephyr implements Mesh protocol layers, and nordic stack implements mesh application layer.

But i couldn't find how I could implement large object transfer via mesh.

Kindly suggest how to implement BLOB transfer & also suggest a sample nCS code to do the same.

Thanks,

Ubaid

Parents Reply Children
  • Hello ,


    You could start off by taking a look at the chat example in NCS

    Thanks for the suggest.

    Can you please help me understand how data reception is happening in Chat sample.

    1. I am to understand that first opcode is registered against handler:

    /* .. include_startingpoint_chat_cli_rst_2 */
    const struct bt_mesh_model_op _bt_mesh_chat_cli_op[] = {
    	{
    		BT_MESH_CHAT_CLI_OP_MESSAGE,
    		BT_MESH_LEN_MIN(BT_MESH_CHAT_CLI_MSG_MINLEN_MESSAGE),
    		handle_message
    	},

    2. Next in "handle_message" procedure data extraction is present:

    static int handle_message(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
    			  struct net_buf_simple *buf)
    {
    	struct bt_mesh_chat_cli *chat = model->user_data;
    	const uint8_t *msg;
    
    	msg = extract_msg(buf);
    
    	if (chat->handlers->message) {
    		chat->handlers->message(chat, ctx, msg);
    	}
    
    	return 0;
    }

    Here it is byte wise data extraction, suppose my received data is custom & I want to extract custom data structure say:

    struct Custom
    {
    int i_data;
    float f_data;
    }

    How can I do that..? in the handler

    Kindly suggest.

  • Hello,

    Sorry about the delay. Have you gotten any further on this, or is what you described below still the current challenge?

    Your understanding of how the chat example works looks correct. 

    Ubaid_M said:
    How can I do that..? in the handler

    You could simply save the msg to that struct of yours. And you might want to modify the handle_chat_message handler in model_handler.c to send the corresponding struct.

    But I think the main challenges lies in how you are going to handle all that data on the application layer. You can't simply make the struct be 350kB and send that. Any packet with size larger than 11 bytes (including header) will be split into segmented messages automatically. But the maximum possible segmented payload size is 380 bytes. This means that you would have to control of what parts of the file are or are not received using the application layer. 

    Regards,
    Elfving

  • Hello ,

    ut the maximum possible segmented payload size is 380 bytes

    Yes agreed to this,

    What I found that payload that is to be transferred is controlled through the configurations:

    CONFIG_BT_MESH_RX_SEG_MAX=100
    CONFIG_BT_MESH_TX_SEG_MAX=100

    So, please help me in understanding, how will my callbacks look (Which APIs I can use and how..?):

    1. when transmitting 100 bytes..?

    2. When receiving 100 bytes..?

    3. And is any other configurations are needed other than CONFIG_BT_MESH_RX_SEG_MAX & CONFIG_BT_MESH_TX_SEG_MAX..?

  • First of all, again I just wanted to stress that Mesh isn't recommended for sending large files. I have seen previous estimates for sending a 300kB file one hop (between two nodes next two each other) taking 5 hours. If you wanted it to be sent to a node on the opposite side of a larger network it would take even longer. 

    Ubaid_M said:

    What I found that payload that is to be transferred is controlled through the configurations:

    Right, the CONFIG_BT_MESH_RX_SEG_MAX configuration will control the maximum amount of allowed segments in a message. Which you can modify yourself in the range [1,32]. Note that if you try to do a pristine build with CONFIG_BT_MESH_RX_SEG_MAX=100, like you demonstrated, it will give you an error. Anything above 32 would go against the Spec. For more info on this, see section 2.3.3 in the Mesh Profile Spec.

    What you can do, is increase the amount of segments to 32. For every segment you can get 12 octets, which turns out to be a total maximum of 377 octets (for a 3-octet opcode). So you can get more than a 100 bytes per message, though it would need to be multiple segments.

    Ubaid_M said:
    And is any other configurations are needed other than CONFIG_BT_MESH_RX_SEG_MAX & CONFIG_BT_MESH_TX_SEG_MAX..

    Yeah put CONFIG_BT_MESH_ADV_BUF_COUNT to at least 35. Besides that I believe Mesh configuration part of the chat example already provides you with some of the more critical ones. 

    Ubaid_M said:

    So, please help me in understanding, how will my callbacks look (Which APIs I can use and how..?):

    I will have to get back to you on this next week.

    Regards,

    Elfving

  • Hello ,


    I will have to get back to you on this next week.

    Kindly suggest on handlers for Client TX of 100 bytes & server RX of 100 bytes.

    Please suggest as per the pseudo-code below:
    Server RX:

    #In prj.conf
    CONFIG_BT_MESH_RX_SEG_MAX=20
    
    //OPcode defn
    #define BT_MESH_RX_100_OP_MESSAGE BT_MESH_MODEL_OP_3( 0x0A , BT_MESH_VENDOR_COMPANY_ID )
    
    #define BT_MESH_PAYLOAD_GET_LEN 100
    static char centLoad[100]= {0};
    const struct bt_mesh_model_op _bt_mesh_vendor_srv_op[] = {
    	{BT_MESH_RX_100_OP_MESSAGE,
    	 BT_MESH_LEN_EXACT( BT_MESH_PAYLOAD_GET_LEN ),
    	 handle_rx100B},
    	 	BT_MESH_MODEL_OP_END,
    };
    
    
    //100bytes rx handler
    static int handle_rx100B( struct bt_mesh_model* model, struct bt_mesh_msg_ctx* ctx, struct net_buf_simple* buf )
    {
        struct bt_mesh_vendor_srv* srv = model->user_data;
        centLoad = net_buf_simple_pull_mem( buf, buf->len ); //buf->len is initialized to 100 from the opcode len definition right..? //
        return ( 0 );
    }
    
    
    
    

    Kindly suggest on this server pseudo code
    And please help me with client handler TX 100 bytes code for this server.

    Thanks,

    Ubaid

Related