Data transmission question between coap client and coap sever

I now have five nrf52833dk_nrf52833 development boards burn the thread client  procedure,and now I want these five development boards  send data  to another nrf52833dk_nrf52833 development board which is burnned the thread sever procedure , How do I change the ip? how do I pair the network? how do I modify the demo program ?

  • The following images show the program names burned to different development boards

  • Hi,

    How do I change the ip?

    Which one? The Link-Local address is based on the IEEE 802.15.4 address, which is stored on the device and configured when the OpenThread stack is initialized. The Mesh-Local IPv6 address is defined in multicast_local_addr so that you can change this to something else:

    /* Thread multicast mesh local address */
    static struct sockaddr_in6 multicast_local_addr = {
    	.sin6_family = AF_INET6,
    	.sin6_port = htons(COAP_PORT),
    	.sin6_addr.s6_addr = { 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    			       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
    	.sin6_scope_id = 0U
    };

    The network topology defines the RLOC address, which will be assigned automatically. You can read more in OpenThread's documentation about IPv6 Addressing.

    how do I pair the network?

    How to pair is explained in the testing section of the sample's documentation. To pair a client with a server, first press button 4 on the server to enable pairing, and then press button 4 on the client to pair it with the server.

    how do I modify the demo program ?

    This depends on what you want the program to do. You can look at how the client sends commands to control the LED on the server. By default, pressing button 2 on the client will multicast a LIGHT_ON or LIGHT_OFF message, and button 1 will unicast it to a paired device. You can change it to make the client send data instead of controlling the light. If you look at the functions toogle_one_light() and toggle_mesh_lights, you will see how the commands are sent:

    static void toggle_one_light(struct k_work *item)
    {
    	uint8_t payload = (uint8_t)THREAD_COAP_UTILS_LIGHT_CMD_TOGGLE;
    
    	ARG_UNUSED(item);
    
    	if (unique_local_addr.sin6_addr.s6_addr16[0] == 0) {
    		LOG_WRN("Peer address not set. Activate 'provisioning' option "
    			"on the server side");
    		return;
    	}
    
    	LOG_INF("Send 'light' request to: %s", unique_local_addr_str);
    	coap_send_request(COAP_METHOD_PUT,
    			  (const struct sockaddr *)&unique_local_addr,
    			  light_option, &payload, sizeof(payload), NULL);
    }
    
    static void toggle_mesh_lights(struct k_work *item)
    {
    	static uint8_t command = (uint8_t)THREAD_COAP_UTILS_LIGHT_CMD_OFF;
    
    	ARG_UNUSED(item);
    
    	command = ((command == THREAD_COAP_UTILS_LIGHT_CMD_OFF) ?
    			   THREAD_COAP_UTILS_LIGHT_CMD_ON :
    			   THREAD_COAP_UTILS_LIGHT_CMD_OFF);
    
    	LOG_INF("Send multicast mesh 'light' request");
    	coap_send_request(COAP_METHOD_PUT,
    			  (const struct sockaddr *)&multicast_local_addr,
    			  light_option, &command, sizeof(command), NULL);
    }

    Best regards,
    Marte

  • Thank you very much for your patience in answering my questions. I have a few more questions

    1、What's the difference between pre-pairing and post-pairing?

    2、Before pairing, multiple clients can simultaneously control the switching on and off of sever's led4. How can I know which client  side controls the server side ? This is also the original intention of me to identify by changing the IP address of the client. Is it feasible? How to find the corresponding identification position in the server program ?

    3、When the client is paired with the server, multiple clients can control led4 of the server side by pressing button 1. May I ask how to identify which client controls the LED4 of the server side in this way?

  • Hi,

    caidehen said:
    1、What's the difference between pre-pairing and post-pairing?

    Pairing lets the client know the server's unicast address so that it can send commands directly to the server instead of multicasting. When you enable pairing on the server, it begins listening for multicast provisioning messages from the client. When you press button 4 on the client, it will send a multicast provisioning request, which the server will receive. The server will then respond to the client with a unicast message, letting the client know the server's address.

    caidehen said:
    2、Before pairing, multiple clients can simultaneously control the switching on and off of sever's led4. How can I know which client  side controls the server side ? This is also the original intention of me to identify by changing the IP address of the client. Is it feasible? How to find the corresponding identification position in the server program ?

    You can print the address of the client in light_request_handler:

    static void light_request_handler(void *context, otMessage *message,
    				  const otMessageInfo *message_info)
    {
    	uint8_t command;
    
    	ARG_UNUSED(context);
    
    	char addressString[OT_IP6_ADDRESS_STRING_SIZE]; 
        otIp6Address peer_addr = message_info->mPeerAddr;
        otIp6AddressToString(&peer_addr, addressString, sizeof(addressString));
    

    caidehen said:
    3、When the client is paired with the server, multiple clients can control led4 of the server side by pressing button 1. May I ask how to identify which client controls the LED4 of the server side in this way?

    The same way as above, by printing the client's address.

    Best regards,
    Marte

  • HI.

    • Thank you very much for your excellent answer. I have one last question for you

    • /* Thread multicast mesh local address */
      static struct sockaddr_in6 multicast_local_addr = {
      	.sin6_family = AF_INET6,
      	.sin6_port = htons(COAP_PORT),
      	.sin6_addr.s6_addr = { 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      			       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
      	.sin6_scope_id = 0U
      };
    • After checking the client code, I found that the function modified the target ip multicast address.
    • The images below are clientaddr and severaddr that I printed out
    •  I want to know how to find the ip address of the client in the client program and modify it
    • Thank you very much and enjoy your work

  • Hi,

    caidehen said:
    After checking the client code, I found that the function modified the target ip multicast address.

    That is correct. As I said, this address is the mesh-local address. It is the same as the multicast address. The address you are printing is the client's link-local address. Please see IPv6 Addressing to understand the different addresses and how they are connected.

    caidehen said:
    I want to know how to find the ip address of the client in the client program

    If you want to find the link-local address of the client on the client, you can use the following API:

    const otIp6Address *otThreadGetLinkLocalIp6Address(otInstance *aInstance);

    For example:

    struct otInstance *instance = openthread_get_default_instance();
    const otIp6Address *address = otThreadGetLinkLocalIp6Address(instance);
    char addressString[OT_IP6_ADDRESS_STRING_SIZE];
    otIp6AddressToString(address, addressString, sizeof(addressString));
    
    LOG_INF("Link-Local addr: %s", addressString);

    caidehen said:
    and modify it

    You cannot modify the link-local address after the OpenThread stack has started. You can add an IPv6 address to the Thread interface on the device, but this will not be the link-local address. To change the link-local address, you must change the IEEE 802.15.4 extended address before the OpenThread stack is initialized, as the link-local address is derived from this address during initialization. You can set the extaddr with otLinkSetExtendedAddress:

    otError error = OT_ERROR_NONE;
    otExtAddress extAddress = {{ 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0xca, 0xfe }};
    struct otInstance *instance = openthread_get_default_instance();
    error = otLinkSetExtendedAddress(instance, &extAddress);

    This will not change the prefix, so it only changes parts of the link-local address.

    Best regards,
    Marte

Related