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.

  • Hi

    Just to double check that you print all the available addresses:
    Could you use the serial interface and do the command:

    ot ipaddr

    Does this return the same addresses as when you log?

    Regards,
    Sigurd Hellesvik

  • Hi,

    It was my bad, ipaddr is available.

    I am using below code to send CoAP message to my CoAP server:

    
    #define BORDER_ROUTER_IP  "2001:db8:1:ffff::a00:1" 
    #define BOOTSTRAP_MESSAGE_FORMAT "o=2&i=1&t=1&2=10"
    #define COMMON_RESOURCE "proxy/zenedge"
    #define EUID "u=64088dce2d8f7568"
    #define PACKET_VERSION "pv=1"
    #define BOOTSTRAP_RESOURCE "pt=b"
    
    /**
     * @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);
    }
    
    
    /**
     * @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(aInstance);
      for (const otNetifAddress *addr = unicastAddrs; addr; addr = addr->mNext) {
        char string[OT_IP6_ADDRESS_STRING_SIZE];
        const otIp6Address add6 = addr->mAddress;
        otIp6AddressToString(&add6, string, sizeof(add6));
        LOG_INF("addr: %s", log_strdup(string));
      }
    }
    
    
    /**
     * @brief send coap packet for bootstraping
     */
    void coap_send_bootstrap_message() {
      struct openthread_context *context = openthread_get_default_context();
      char buff[30];
      char *bootstrap_message_payload = NULL;
      sprintf(buff, BOOTSTRAP_MESSAGE_FORMAT);
      bootstrap_message_payload = (char *)malloc(30);
      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, COAP_METHOD_POST);
        otCoapMessageGenerateToken(p_message, 2);
        otCoapMessageAppendUriPathOptions(p_message, COMMON_RESOURCE);
        otCoapMessageAppendUriQueryOption(p_message, EUID);
        otCoapMessageAppendUriQueryOption(p_message, PACKET_VERSION);
        otCoapMessageAppendUriQueryOption(p_message, BOOTSTRAP_RESOURCE);
        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);
    
        LOG_INF("Send Bootstarp message");
        error = otCoapSendRequest(context->instance, p_message, &message_info, bootStrapCallBack, NULL);
        
      } while (false);
      LOG_INF("*********Print node address********* ");
      addresses_print(context->instance);
    
      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");
      }
      free(bootstrap_message_payload);
    }
    
     

    Bur while sending the coap message I am receiving the following error.

    [00:09:12.965,362] <inf> coap_client_utils: Send Bootstarp message
    [00:09:12.965,454] <inf> coap_client_utils: *********Print node address*********
    [00:09:12.965,454] <inf> coap_client_utils: Print IPv6 address of node
    [00:09:12.965,637] <inf> coap_client_utils: addr: feef:ee:0:0:267
    [00:09:12.965,820] <inf> coap_client_utils: addr: fdf2:8f4:1bb2:b
    [00:09:12.966,033] <inf> coap_client_utils: addr: fdf2:8f4:1bb2:b
    [00:09:12.966,217] <inf> coap_client_utils: addr: fe80:0:0:0:f6ce
    [00:09:12.966,217] <inf> coap_client_utils: Failed to send config CoAP Request: 13

    This Error code:'13' pertains to "OT_ERROR_INVALID_STATE" . In what condition do we get this response?

    Do I need to initialize something which is being missed?

  • Hi

    Bhumika said:
    Do I need to initialize something which is being missed?

    Yes, this is likely.

    To figure out exactly what is missing, find where the error is set in the CoAP library.

    Regards,
    Sigurd Hellesvik

  • I have seen function definition in "modules//lib/openthread/src/core/api/coap_api.cpp". But its generic return messages doesn't contain this return message.

    can you help in debugging?

     

  • Hi

    Which function definition?

    Which IDE are you using for developement?

    Regards,
    Sigurd Hellesvik

Related