Appkey always equals 0 in my custom model in BT mesh

Hello everyone,

I'm currently trying to create Bluetooth mesh custom client and server with the nrf connect sdk. 

The purpose of my application is to make my server send data automatically to my client when it receives a particular message from it.

A very common type of communication between a server and a client !

To send a message to my server, my client use the model publication context configurated by the Configuration Client Model. (so I use publish function)
To send a message to my client, my server use the publication context of my client request to respond to the client. (So I use send function)

My problem is that my server failed to respond to my client because the Appkey that it receives from my client always equals zero, and it doesn't recognize it. I have this error :

"E : Model don't bound to AppKey 0x000"

After this error, my server is no longer able to receive messages from my client.

I use the phone app nrf mesh to provision my node and to provide an AppKey to my Client and my Server.

If you have any idea about what can cause this problem it would be very helpful !

Parents
  • Hi,

    Could you supply me with some more info about the following: 

    1. Can you verify if you are working with nRF Connect SDK and if so what version are you using?
    2. Is "E : Model don't bound to AppKey 0x000" the exact error message you are receiving or is it translated to English? 
    3. You state you're using the nRF Mesh application to provision your node. Can you state which phone OS you are using (and what version of the mobile application)?
    4. Did you base your custom application on any existing samples? If so, could you supply them to me?

    Kind regards,
    Andreas

  • Hi,

    thanks for your reply ! For a strange reason it works now ... I don't succeed to identify the source of the problem... And I don't really like it because I didn't do something in particular and I'm afraid that the problem will reappear.

    So I give you the answers just in case :

    1. I work with nRF connect sdk on visual studio code, v1.9.1 release
    2. Yes it was the exact error message that I received when I connected my nrf52840 in serial and I started communication

    3. I use nrf Mesh 3.2.4 on an Androïd phone
    4. I base my custom application on several examples such as the generic OnOff models in the nrf sdk and the chat sample

    kind regards

  • Hi,

    lalum said:
    For a strange reason it works now ... I don't succeed to identify the source of the problem...

    I'm glad to hear that the issue has fixed itself automagically! 

    I'll let the case stay open in case you manage to reproduce the issue and we need to look closer into it again

    Kind regards,
    Andreas

Reply Children
  • Hi Andreas,

    my problem reappeared. I think my problem is that I don't really understand how the Appkeys are bound to models...

    This time my server receive the message from my client and when it wants to respond I have this error : "E : Model not bound to Appkey 0x2000".

    So to give you more information, this is my function which handle the message sent by the client: (my client send a request to my server with an offset and a size to read datas in a particular area of the RAM)

    static int bt_mesh_handle_message_request(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf){
        printk("SERVER : receive request message \n");
    	uint32_t receive_offset = net_buf_simple_pull_le32(buf);
    	size_t receive_size = net_buf_simple_pull_le32(buf);
    	printk("SERVER : receive offset = %d and size = %zu \n", receive_offset, receive_size);
    
    	struct bt_mesh_datas_state datas_state_srv = {
    		.address = SHARED_RAM_ADDRESS + receive_offset,
    		.datas = (uint32_t *) datas_state_srv.address,
    		.remaining_datas = receive_size 
    	};
    
    	struct k_thread my_thread_data;
    	printk("DEBUG : create thread \n");
    	k_thread_create(&my_thread_data, &my_thread_stack, STACKSIZE, My_thread, model, ctx, &datas_state_srv, PRIORITY, 0, K_NO_WAIT);
    	return 0;
    }

    This handler create a thread that I want to use to split the data into packets and send them. But to begin, I just want to send at least on packet in this thread to test, so the thread looks like this :

    void My_thread(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *rx_ctx, struct bt_mesh_datas_state *datas_state_srv){
    	
    	printk("DEBUG : In the thread \n");
    	BT_MESH_MODEL_BUF_DEFINE(msg, BT_MESH_MESH_OP_DATAS, 1);
    	bt_mesh_model_msg_init(&msg, BT_MESH_MESH_OP_DATAS);
    
    	net_buf_simple_add(&msg, 5);
    	(void) bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL);
    	printk("DEBUG : send message ok \n");
    
    	while(1){
    
    		printk("DEBUG : thread finished \n");
    		k_usleep(100000000000);
    	}	
    	return;
    }

    when I try to debug, I see that the rx_ctx-> app_idx = 0x2000 and model->key is empty ... But I don't understand why model->key is empty because I bound an Appkey to my server and client models in the nRF mesh app...

    Sorry I'm very new with zephyr, nordic and BT mesh and I try to understand !

    Kind regards

  • Hi, 

    I will see if I can find someone who can explain how Appkeys work better than me and can explain both of us how it works. Unfortunately we hit a bit of a bad timing where we have an overlap where most of the Mesh experts are out on vacation this week, but nonetheless I've asked the team for some input. I can hopefully return you with an answer and an explaination on Monday/early next week.

    I hope the delayed response time does not cause any issues for you,

    Kind regards,
    Andreas

  • Hi,

    thank you very much for your answer !

    After analysis it seems that it is "Appkey index" and not the Appkey that I am returning... The value "0" that I have would therefore correspond to the Appkey at index 0 of the Appkey list related to my model. In my case I only assigned one appkey to my model. But that's just my theory...

    In any case I have a problem with my thread... I give it the value "ctx" as an argument and this value is modified automatically in my thread !

    The value of ctx->app_idx is indeed equal to 0 in my reception function "bt_mesh_handle_message_request" but once in the thread "My_thread" the value rx_ctx->app_idx is equal to 0x2000... I don't understand why the value of ctx changes without my intervention. I tried to put the ctx value as a global variable and thus not pass ctx as an argument of my thread, but the result is the same, once in the thread rx_ctx->app_idx = 0x2000....

    I fully understand that no one is available to answer me during this holiday period and thank you for your time! I can wait for the beginning of next week to have a solution

    King regards

  • Hi,

    I have some additional information/update for you.

    You might already know this, but I am adding this nonetheless to cl

    An application key is used in the network to separate acess rights to the different applications in a network. Every application has their own key. When a Mesh pack is sendt in the network, it will be encrypted with an application key, and unless the model is bound with the correct application key, then a node will not be able to decrypt the message.

    lalum said:
    The value of ctx->app_idx is indeed equal to 0 in my reception function "bt_mesh_handle_message_request" but once in the thread "My_thread" the value rx_ctx->app_idx is equal to 0x2000... I don't understand why the value of ctx changes without my intervention. I tried to put the ctx value as a global variable and thus not pass ctx as an argument of my thread, but the result is the same, once in the thread rx_ctx->app_idx = 0x2000....

    As for why this is happening I will need to ask around some more. Let me know if you've managed it to work in the mean while, and thank you for your patience so far

    Kind regards,
    Andreas

  • Hi Andreas,

    Thank you for the additional information. It confirms what I understood. To make my communication works, I decided to retrieve only the destination address and to pass it as an argument of my thread.

    static int bt_mesh_handle_message_request(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf){
        printk("SERVER : receive request message \n");
    	uint32_t receive_offset = net_buf_simple_pull_le32(buf);
    	size_t receive_size = net_buf_simple_pull_le32(buf);
    	printk("SERVER : receive offset = %d and size = %zu \n", receive_offset, receive_size);
    
    	struct bt_mesh_datas_state datas_state_srv = {
    		.address = SHARED_RAM_ADDRESS + receive_offset,
    		.datas = (uint32_t *) datas_state_srv.address,
    		.remaining_datas = receive_size 
    	};
    
    	struct k_thread my_thread_data;
    	printk("DEBUG : create thread \n");
    	uint16_t addr = ctx->addr;
    	k_thread_create(&my_thread_data, &my_thread_stack, STACKSIZE, thread, model, addr, &datas_state_srv, PRIORITY, 0, K_NO_WAIT);
    	return 0;
    }

    and in my thread I recreate a publication context :  

    void My_thread(struct bt_mesh_model *model, uint16_t address, struct bt_mesh_datas_state *datas_state_srv){
    
    	printk("DEBUG : Thread created \n");
    	struct bt_mesh_msg_ctx ctx = {
    		.addr = address,
    		.app_idx = model->keys[0],
    		.send_ttl = BT_MESH_TTL_DEFAULT,
    	};
    	
    	BT_MESH_MODEL_BUF_DEFINE(msg, BT_MESH_OP_DATAS, 1);
    	bt_mesh_model_msg_init(&msg, BT_MESH_OP_DATAS);
    
    	net_buf_simple_add(&msg, 5);
    	(void) bt_mesh_model_send(model, ctx, &msg, NULL, NULL);
    	printk("DEBUG : send message ok \n");
    
    	while(1){
    
    		printk("DEBUG : thread finished \n");
    		k_usleep(100000000000);
    	}	
    	return;

    It works ... but It doesn't explain why the first code doesn't work ...
    I hope somebody in your team have the explanation !

    Kind regards

Related