This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Assign both CoAP client and server roles to a node in nRF_Connect_SDK

Hi,

In nRF_Connect_SDK's OpenThread's Coap_Client sample, I want to implement the role of both client and server on a single node.

Also instead of sending messages to CoAP_Server, I want to send messages to my own CoAP server, whose address I have specified in the application. Following is the application code...

#define BORDER_ROUTER_IP "2001:db8:1:ffff::a00:1"
#define COMMON_RESOURCE "proxy/zenedge"
#define EUID "u=64088dce2d8f7568"
#define PACKET_VERSION "pv=1"
#define BOOTSTRAP "pt=b"

#define BOOTSTRAP_MESSAGE_FORMAT "o=2&i=1&t=1&2=10&o=2&i=2&t=2&2=11&o=2&i=5&t=4&2=11&o=2&i=6&t=5&2=7&o=3&i=4&t=7&2=5&o=3&i=7&t=8&2=12&o=2&i=8&t=3&2=11&o=2&i=11&t=22&2=5&o=2&i=12&t=31&2=11"

/**
 * @brief Bootstrap callback
 * @param aContext Not used
 * @param aMessage coap message
 * @param aMessageInfo Not used
 * @param aError  Error happened during receiving of coap message
 */
void bootStrapCallBack(
        void *aContext,
        otMessage *aMessage,
        const otMessageInfo *aMessageInfo,
        otError aError) {
    uint32_t length = otMessageGetLength(aMessage) - otMessageGetOffset(aMessage);
    uint8_t buff_callback[256];

    if (aError != OT_ERROR_NONE) {
        LOG_INF("(bootstrap call_back) Error receiving coap response message: Error %d: %s\r\n", aError,
                otThreadErrorToString(aError));
    } else {
        if (otCoapMessageGetCode(aMessage) == OT_COAP_CODE_CONTENT) {

            LOG_INF("(bootstrap call_back) Response received successfully\n\r");
            if (length < 256) {
                otMessageRead(aMessage, otMessageGetOffset(aMessage), buff_callback, length);
                LOG_INF("%s\n\r", buff_callback);
            } else {
                LOG_INF("Response length too lengthy\n");
            }
        } else {
            LOG_INF("Response code is %d,  %s\r\n", otCoapMessageGetCode(aMessage),
                    otThreadErrorToString(otCoapMessageGetCode(aMessage)));
        }
    }
    OT_UNUSED_VARIABLE(aContext);
    OT_UNUSED_VARIABLE(aMessageInfo);
}

/**
 * @brief send coap packet for bootstraping
 */
void coap_send_bootstrap_message() {

    char buff[512];
    char *bootstrap_message_payload = NULL;
    sprintf(buff, BOOTSTRAP_MESSAGE_FORMAT);
    bootstrap_message_payload = (char *)malloc(512);
    strcpy(bootstrap_message_payload, buff);

    otMessageInfo message_info;
    otMessage *p_message;
    otError error = OT_ERROR_NONE;
    do {
        p_message = otCoapNewMessage(openthread_get_default_instance(), NULL);

        otCoapMessageInit(p_message, OT_COAP_TYPE_CONFIRMABLE, OT_COAP_CODE_POST);
        otCoapMessageGenerateToken(p_message, 2);
        otCoapMessageAppendUriPathOptions(p_message, COMMON_RESOURCE);
        otCoapMessageAppendUriQueryOption(p_message, EUID);
        otCoapMessageAppendUriQueryOption(p_message, PACKET_VERSION);
        otCoapMessageAppendUriQueryOption(p_message, BOOTSTRAP);
        otCoapMessageSetPayloadMarker(p_message);
        if (p_message == NULL) {
            LOG_INF("Failed to allocate config message for CoAP Request\r\n");
            break;
        }
        error = otMessageAppend(p_message, bootstrap_message_payload, strlen(bootstrap_message_payload));
        if (error != OT_ERROR_NONE) {
            break;
        }
        memset(&message_info, 0, sizeof(message_info));
        message_info.mPeerPort = COAP_PORT;
        otIp6AddressFromString(BORDER_ROUTER_IP, &message_info.mPeerAddr);

        error = otCoapSendRequest(openthread_get_default_instance(), p_message, &message_info, bootStrapCallBack, NULL);

    } while (false);

    if (error != OT_ERROR_NONE && p_message != NULL) {
        LOG_INF("Failed to send config CoAP Request: %d\r\n", error);
        otMessageFree(p_message);
    } else {
        LOG_INF("Packet sent successfully");
    }
    return error;
}

As per logs, my packet is being sent, but I don't receive any packet on my CoAP Server interface.

can you suggest if I need to enable any specific configuration in prj.conf or anywhere in the code.

  • can you suggest what is wrong with this implementation, why my code is crashing?

  • Hi

    Your error message says:

    [00:00:00.378,051] <err> os: Fault during interrupt handling
    [00:00:00.378,082] <err> os: Current thread: 0x200015b8 (logging)

    The fault happens in your logging, and seems to be connected to interrupts.
    I advise that you investigate these in your program to try to find the issue.

    Regards,
    Sigurd Hellesvik

  • hi,

    I have tried again and reviewed my code.

    I couldn't find any error with any interrupt.

    Code crashed only while calling addresses_print function.

    The attached code for the address print function is as follow:

    /**
     * @param openthread instance
     * @action print address of device
     */
    static void addresses_print(otInstance *aInstance) {
      LOG_INF("Print IPv6 address of node");
      const otNetifAddress *unicastAddrs = otIp6GetUnicastAddresses(openthread_get_default_instance());
      LOG_INF("Assigned 1");
    
      for (const otNetifAddress *addr = unicastAddrs; addr; addr = addr->mNext) {
        LOG_INF("***Inside Loop 1.1***");
        char string[OT_IP6_ADDRESS_STRING_SIZE];
        const otIp6Address add6 = addr->mAddress;
        LOG_INF("***Inside Loop 1.2***");
       // otIp6AddressToString(&add6, string, sizeof(add6));
        LOG_INF("addr: %s\n", string);
      }
    }

    Kindly look into it and help me in finding the cause of this crash.

  • Hi

    You need to add strdup to the logging. See Logging v1

    LOG_INF("addr: %s\n", log_strdup(string));
    

    Regards,
    Sigurd Hellesvik

  • In Old SDK (nrf_SDK_for_Thread_and_Zigbee_4.1.0), which is working with Border router here are the address:

    <info> app: feef:ee:0:0:3b06:a24d:2625:50e7
    
    <info> app: fdf2:8f4:1bb2:b82a:0:ff:fe00:1c0d
    
    <info> app: fdf2:8f4:1bb2:b82a:800c:e83b:2bf4:518a
    
    <info> app: fe80:0:0:0:7b9f:ccb1:dca1:e627

    In nRF_Connect_SDK(v1.8.0), following address are formed:

    [00:00:00.785,766] <inf> coap_client_utils: addr: fdf2:8f4:1bb2:b
    [00:00:00.785,949] <inf> coap_client_utils: addr: fdf2:8f4:1bb2:b
    [00:00:00.786,132] <inf> coap_client_utils: addr: fe80:0:0:0:f6ce

    And following addresses are formed on my border router which hosts the CoAP Server:

     inet6 feef:ee::be40:d9ae:ce19:5dbc  prefixlen 64  scopeid 0x40<site>
            inet6 fe80::d4c8:801f:ac75:6cb5  prefixlen 64  scopeid 0x20<link>
            inet6 fdf2:8f4:1bb2:b82a:94a5:bb8d:4716:6657  prefixlen 64  scopeid 0x0<global>
            inet6 fe80::1ac8:b1c:d7f9:a06c  prefixlen 64  scopeid 0x20<link>

    So my understanding is that in my nRF_Connect_SDK based node, fix mesh prefix-based address is not formed, i.e. address with prefix: "feef:ee"

    Can you tell me how to form this address?

Related