CoAP Server Example is not working
Risposta
13/06/19 9.28

Dear Community,

I'm implementing a CoAP Rest Server in my XDK for the project that I'm developing. I based my code on the example provided in the developers page ("https://developer.bosch.com/web/xdk/coap") and after I clean, build and flash it in my XDK it runs with no errors, but when I make a Client request the server doesn't respond. I made a manual debug with simple printf and I discovered that the "coapReceiveCallback" function is not being ran. When I try to implement a Client on XDK it works perfectly, so the Client request isn't the problem, because if I make the same request to another server I have a response.

I will leave my code down below and my application.mk file. I need to solve this problem ASAP. Can someone help me with this? Please take a look at my code.

Thank you.

Best Regards

Pedro S.

#include "XdkAppInfo.h"
#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_APP_CONTROLLER

#include <stdio.h>

#include "BCDS_CmdProcessor.h"
#include "FreeRTOS.h"

#include "BCDS_WlanConnect.h"
#include "BCDS_NetworkConfig.h"
#include "BCDS_ServalPal.h"
#include "BCDS_ServalPalWiFi.h"

#include "Serval_Coap.h"
#include "Serval_CoapServer.h"

/* --------------------------------------------------------------------------- |
 * HANDLES ******************************************************************* |
 * -------------------------------------------------------------------------- */

static CmdProcessor_T * AppCmdProcessor;
static CmdProcessor_T CmdProcessorHandleServalPAL;

/* --------------------------------------------------------------------------- |
 * VARIABLES ***************************************************************** |
 * -------------------------------------------------------------------------- */

#define TASK_PRIORITY_SERVALPAL_CMD_PROC            UINT32_C(3)
#define TASK_STACK_SIZE_SERVALPAL_CMD_PROC          UINT32_C(600)
#define TASK_QUEUE_LEN_SERVALPAL_CMD_PROC           UINT32_C(10)

/* --------------------------------------------------------------------------- |
 * EXECUTING FUNCTIONS ******************************************************* |
 * -------------------------------------------------------------------------- */

static Retcode_T ServalPalSetup(void)
{
    Retcode_T returnValue = RETCODE_OK;
    returnValue = CmdProcessor_Initialize(&CmdProcessorHandleServalPAL, (char *)"Serval PAL", TASK_PRIORITY_SERVALPAL_CMD_PROC, TASK_STACK_SIZE_SERVALPAL_CMD_PROC, TASK_QUEUE_LEN_SERVALPAL_CMD_PROC);

    if (RETCODE_OK == returnValue)
    {
        returnValue = ServalPal_Initialize(&CmdProcessorHandleServalPAL);
    }
    if (RETCODE_OK == returnValue)
    {
        returnValue = ServalPalWiFi_Init();
    }
    if (RETCODE_OK == returnValue)
    {
        ServalPalWiFi_StateChangeInfo_T stateChangeInfo = { SERVALPALWIFI_OPEN, 0 };
        returnValue = ServalPalWiFi_NotifyWiFiEvent(SERVALPALWIFI_STATE_CHANGE, &stateChangeInfo);
    }
    return returnValue;
}

void networkSetup(void) {

    WlanConnect_SSID_T connectSSID = (WlanConnect_SSID_T) "OvrR4g002_2.4G";
    WlanConnect_PassPhrase_T connectPassPhrase =
            (WlanConnect_PassPhrase_T) "Welcome@OvrP";
    WlanConnect_Init();
    NetworkConfig_SetIpDhcp(0);
    WlanConnect_WPA(connectSSID, connectPassPhrase, NULL);

    ServalPalSetup();
}

void createCoapResponse(Msg_T *msg_ptr, char const *payload_ptr, uint8_t responseCode){
    CoapSerializer_T serializer;
    CoapSerializer_setup(&serializer, msg_ptr, RESPONSE);
    CoapSerializer_setCode(&serializer, msg_ptr, responseCode);
    CoapSerializer_setConfirmable(msg_ptr, false);
    CoapSerializer_reuseToken(&serializer, msg_ptr);

    CoapOption_T uriOption;
    uriOption.OptionNumber = Coap_Options[COAP_URI_PATH];
    uriOption.value = (uint8_t*) "test";
    uriOption.length = 4;
    CoapSerializer_serializeOption(&serializer, msg_ptr, &uriOption);

    CoapSerializer_setEndOfOptions(&serializer, msg_ptr);
    // serialize the payload
    uint8_t resource[30] = {0};
    uint8_t resourceLength = strlen(payload_ptr);
    memcpy(resource, payload_ptr, resourceLength + 1);
    CoapSerializer_serializePayload(&serializer, msg_ptr, resource, resourceLength);
}

Retcode_T sendingCallback(Callable_T *callable_ptr, Retcode_T status){
    (void) callable_ptr;
    (void) status;
    return RC_OK;
}

void sendCoapResponse(Msg_T *message, char const* payloard_ptr){
    createCoapResponse(message, payloard_ptr, Coap_Codes[COAP_CONTENT]);
    Callable_T *alpCallable_ptr = Msg_defineCallback(message,
            (CallableFunc_T) sendingCallback);
    CoapServer_respond(message, alpCallable_ptr);
}

void parseCoapRequest(Msg_T *msg_ptr, uint8_t *code){
    CoapParser_T parser;
    CoapParser_setup(&parser, msg_ptr);
    *code = CoapParser_getCode(msg_ptr);
    const uint8_t* payload;
    uint8_t payloadlen;
    CoapParser_getPayload(&parser,&payload,&payloadlen);
    printf("Incoming Coap request: %s \n\r",payload);
}

Retcode_T coapReceiveCallback(Msg_T *msg_ptr, Retcode_T status){

	printf("Request received!\n");  //Printf to ensure that the callback function is called

	uint8_t code = 0;
    parseCoapRequest(msg_ptr, &code);
    if(code == Coap_Codes[COAP_POST])
    {
        sendCoapResponse(msg_ptr, "Hello Client, POST received");
    }
    else if(code == Coap_Codes[COAP_GET])
    {
        sendCoapResponse(msg_ptr, "Hello Client, GET Received!");
    }

    return status;
}

/* --------------------------------------------------------------------------- |
 * BOOTING- AND SETUP FUNCTIONS ********************************************** |
 * -------------------------------------------------------------------------- */

static void AppControllerEnable(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);

    vTaskDelay(5000);
    Ip_Port_T serverPort = Ip_convertIntToPort((uint16_t)5683);

    CoapServer_startInstance(serverPort,(CoapAppReqCallback_T) &coapReceiveCallback);

    NetworkConfig_IpSettings_T myIp;
    NetworkConfig_GetIpSettings(&myIp);
    vTaskDelay(5000);
    printf("The IP was retrieved: %u.%u.%u.%u \n\r",
            (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 3)),
            (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 2)),
            (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 1)),
            (unsigned int) (NetworkConfig_Ipv4Byte(myIp.ipV4, 0)));
}

static void AppControllerSetup(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode = RETCODE_OK;

    /* Setup the necessary modules required for the application */
    networkSetup();
    CoapServer_initialize();

    retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerEnable, NULL, UINT32_C(0));
    if (RETCODE_OK != retcode)
    {
        printf("AppControllerSetup : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

void AppController_Init(void * cmdProcessorHandle, uint32_t param2)
{
    BCDS_UNUSED(param2);

    Retcode_T retcode = RETCODE_OK;

    if (cmdProcessorHandle == NULL)
    {
        printf("AppController_Init : Command processor handle is NULL \r\n");
        retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER);
    }
    else
    {
        AppCmdProcessor = (CmdProcessor_T *) cmdProcessorHandle;
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerSetup, NULL, UINT32_C(0));
    }

    if (RETCODE_OK != retcode)
    {
        Retcode_RaiseError(retcode);
        assert(0); /* To provide LED indication for the user */
    }
}

 

0 (0 Voti)
RE: CoAP Server Example is not working
Risposta
19/06/19 9.03 come risposta a Pedro Silva.

hi Pedro

We are looking into this ..

Will get back to you shortly

Thanks

Priyashi

0 (0 Voti)
RE: CoAP Server Example is not working
Risposta
19/06/19 10.59 come risposta a Priyashi Yadav.

Hi Pedro

I would like to know the steps you followed for testing the code.

It would be great if you could mention the steps used for testing your code , So that we could do the same and help you more on that.

Thanks

Priyashi

+1 (1 Voto)
RE: CoAP Server Example is not working
Risposta
19/06/19 11.38 come risposta a Priyashi Yadav.

Hello Priyashi,

For testing I implemented a python client application (I already tested the client with a external coap server and it works perfectly), and configured the port to be the default one (5683).

After that, I created a simple network with an AP to insure that the XDK and the client established a connection.

Next step, I turned on the xdk and waited till the server is ready (I created a printf after the function CoapServer_StartInstance(...)), then I see the ip address of the server and set the client to that ip, next I confirm if the XDK is in the right network and finaly I run the client to send the request! I already tried to ping the server from the client machine and it works fine!

What happens is that, the coapReceiveCallback function is not being called...

 

I hope we can solve this problem! Thank you!

 

Kind Regards

Pedro S.

0 (0 Voti)
RE: CoAP Server Example is not working
Risposta
21/06/19 9.18 come risposta a Pedro Silva.

Hi Pedro

Refer the following implementation

/**
 * Copyright (c) 2010 - 2013 Robert Bosch GmbH and its subsidiaries.
 * All rights reserved.
 *
 * This program is Bosch Internal Open Source.
 * It can be used, redistributed and/or modified under the terms the terms of
 * the Bosch Internal Open Source License v3.3 (BIOSL).
 *
 * A copy of this license accompanies this distribution.
 * If such a file is not present, a copy of this license is available at
 * http://rb-bios-com4t.bosch.com/BIOSL-3_3.txt
 *
 * This code is example code. As a special exception, the copyright holders
 * of this code give you permission to incorporate this example in full or
 * in part in your application and release this application under terms of
 * your choice provided that
 * a) your work is in itself copyrightable and that
 * b) you take over full product warranty and liability
 */

/**
 * Copyright holders:
 *
 * Bosch Sicherheitssysteme GmbH
 *
 */
#include "CoapServerApp.h"

#if SERVAL_ENABLE_COAP_SERVER

#include <Serval_Network.h>
#include <Serval_Log.h>
#include <Serval_Timer.h>
#include <Serval_Msg.h>
#include <Serval_Coap.h>
#include <Serval_CoapServer.h>

#define LOG_MODULE "CCA"

static retcode_t parseRequest(Msg_T *msg_ptr, uint8_t *token,
                              uint8_t *tokenLength, char *uriPath, uint8_t *code);
static retcode_t createResponse(Msg_T *msg_ptr, char const *payload_ptr,
                                uint8_t *tokenLength, uint8_t *token, uint8_t responseCode);

/*
 * Send Callback
 */
static retcode_t Sentcallback(Callable_T *callable_ptr UNUSED,
                              retcode_t status UNUSED)
{
	LOG_TRACE_ENTER_ARGS("%p, %i", callable_ptr, status);

	/* TODO: Implement proper reaction, for example: report error if
	 * status != RC_OK
	 */

	LOG_TRACE_EXIT();

	return RC_OK;
}

/*
 * App callback
 * This function is called for every incoming request.
 */
static retcode_t CoapServer_AppCallback(Msg_T *msg_ptr, retcode_t status)
{
	retcode_t rc = RC_OK;

	if(status != RC_OK)
	{
		LOG_DEBUG("AppCallback status ="
		          RC_RESOLVE_FORMAT_STR "\n", RC_RESOLVE(status));

		rc = status;

		goto sendResponse;
	}

	/* we parse the request to get the Token, URI Path and the code value. */
	uint8_t token[8] = {0};
	uint8_t tokenLength = 0;
	char uriPath[COAP_MAX_URI_LENGTH] = {0};
	uint8_t codeValue = 0;

	rc = parseRequest(msg_ptr, token, &tokenLength, uriPath, &codeValue);

	if(rc != RC_OK)
	{
		LOG_DEBUG("parse request error, rc="
		          RC_RESOLVE_FORMAT_STR "\n", RC_RESOLVE(rc));

		rc = createResponse(msg_ptr, NULL, &tokenLength, token,
		                    Coap_Codes[COAP_INTERNAL_SERVER_ERROR]);

		goto sendResponse;
	}

	if(codeValue != Coap_Codes[COAP_GET])
	{
		/* our resource can be only accessed via GET method. Thus we send
		 * METHOD_NOT_ALLOWED for all other methods */
		rc = createResponse(msg_ptr, NULL, &tokenLength, token,
		                    Coap_Codes[COAP_METHOD_NOT_ALLOWED]);

		goto sendResponse;
	}

	if(strcmp(uriPath, "example/"))
	{
		/* we only provide the resource /example. Thus we send NOT_FOUND for all
		 * other resources. */
		rc = createResponse(msg_ptr, NULL, &tokenLength, token,
		                    Coap_Codes[COAP_NOT_FOUND]);

		goto sendResponse;
	}

	rc = createResponse(msg_ptr, "test", &tokenLength, token,
	                    Coap_Codes[COAP_CONTENT]);

sendResponse:

	if(rc != RC_OK)
	{
		LOG_DEBUG("create response error, rc="
		          RC_RESOLVE_FORMAT_STR "\n", RC_RESOLVE(rc));

		rc = RC_COAP_SEND_RESET_MESSAGE;
	}

	if(rc == RC_OK)
	{
		Callable_T *alpCallable_ptr = Msg_defineCallback(msg_ptr, Sentcallback);

		rc = CoapServer_respond(msg_ptr, alpCallable_ptr);

		if(rc != RC_OK)
		{
			LOG_DEBUG("push response error, rc="
			          RC_RESOLVE_FORMAT_STR "\n", RC_RESOLVE(rc));
		}
	}

	return rc;
}

retcode_t CoapServerApp_initialize(void)
{
	retcode_t rc = RC_OK;

	rc = CoapServer_initialize();

	return rc;
}


retcode_t CoapServerApp_start(Ip_Port_T port)
{
	retcode_t rc = RC_OK;

	rc = CoapServer_startInstance(port, &CoapServer_AppCallback);

	return rc;
}


/*
 * Helper function to create a CoAP response. Token, Response Code and Payload
 * are given via input parameters.
 */
static retcode_t createResponse(Msg_T *msg_ptr, char const *payload_ptr,
                                uint8_t *tokenLength, uint8_t *token, uint8_t responseCode)
{
	retcode_t rc = RC_OK;

	uint8_t resource[COAP_MAX_RESOURCE_LENGTH]  = {0};
	uint8_t resourceLength = 0;

	CoapSerializer_T serializer;

	CoapOption_T opt;
	uint8_t numOfOptions = 0;

	rc = CoapSerializer_setup(&serializer, msg_ptr, RESPONSE);

	if(rc == RC_OK)
	{
		rc = CoapSerializer_setCode(&serializer, msg_ptr, responseCode);
	}

	if(rc != RC_OK)
	{
		LOG_DEBUG("setCode error, rc="
		          RC_RESOLVE_FORMAT_STR "\n", RC_RESOLVE(rc));
	}

	if(rc == RC_OK && payload_ptr != NULL)
	{
		uint16_t formatValue;
		opt.OptionNumber = Coap_Options[COAP_CONTENT_FORMAT];
		CoapSerializer_setUint16(&opt, Coap_ContentFormat[TEXT_PLAINCHARSET_UTF8],
		                         &formatValue);
		rc = CoapSerializer_serializeOption(&serializer, msg_ptr, &opt);
		numOfOptions++;
	}

	if(rc == RC_OK && *tokenLength > 0)
	{
		opt.OptionNumber = Coap_Options[COAP_TOKEN];
		opt.length = *tokenLength;
		opt.value = token;
		rc = CoapSerializer_serializeOption(&serializer, msg_ptr, &opt);
		numOfOptions++;
	}

	CoapSerializer_setEndOfOptions(&serializer, msg_ptr);

	if(rc == RC_OK && payload_ptr != NULL)
	{
		resourceLength = strlen(payload_ptr);
		memcpy(resource, payload_ptr, resourceLength + 1);

		rc = CoapSerializer_serializePayload(&serializer, msg_ptr, resource,
		                                     resourceLength);
	}

	return rc;
}

/*
 * Helper function to retrieve Code, Token and URI-Path from given message
 * pointer.
 */
static retcode_t parseRequest(Msg_T *msg_ptr, uint8_t *token,
                              uint8_t *tokenLength, char *uriPath, uint8_t *code)
{
	retcode_t rc = RC_OK;

	CoapParser_T parser;

	/* always returns RC_OK */
	CoapParser_setup(&parser, msg_ptr);

	*code = CoapParser_getCode(msg_ptr);

	memset(uriPath, 0, COAP_MAX_URI_LENGTH);
	CoapOption_T option;

	/* Retrieve Token */
	rc = CoapParser_getOption(&parser, msg_ptr, &option,
	                          Coap_Options[COAP_TOKEN]);

	if(rc == RC_OK)
	{
		/* no empty token in request used */
		memcpy(token, option.value, option.length);
		*tokenLength = option.length;
	}

	/* Retrieve URI Path */
	rc = CoapParser_getOption(&parser, msg_ptr, &option,
	                          Coap_Options[COAP_URI_PATH]);

	if(rc != RC_OK)
	{
		goto exit;
	}
	memcpy(uriPath, option.value, option.length);
	uriPath[option.length] = '/';

exit:

	return rc;
}
#endif /* SERVAL_ENABLE_COAP_SERVER */

Thanks

Priyashi

+1 (1 Voto)
RE: CoAP Server Example is not working
Risposta
25/06/19 10.16 come risposta a Priyashi Yadav.

Hello Priyashi,

First of all thank you very much for your reply!

I have one question, where do I need to implement this code? This function is used for the client implementation, in the server side I'm just getting compilation errors...

I can't find the "CoapServerApp.h" library anywhere!

Did you try to implement the function in the server? Did it worked?

 

Thanks again.

 

Kind Regards,

Pedro S.

0 (0 Voti)
RE: CoAP Server Example is not working
Risposta
26/06/19 4.13 come risposta a Pedro Silva.

Hi Pedro

The code was posted to check the implementation with your current implementation.

You have to compare your implementation with the Source code provided.

Thanks

Priyashi

+1 (1 Voto)
RE: CoAP Server Example is not working
Risposta
26/06/19 13.51 come risposta a Priyashi Yadav.

Hello Priyashi,

I compared both codes and, until now, I haven’t reach any relevant conclusion. Both implementation should work with no issues.

I’ve tested my network configuration in a CoAP client implementation and it worked with no problems. The network setting is not the problem.

Hope we can find a solution ASAP. Thanks for your answers.

Regards,

Pedro S.

0 (0 Voti)
RE: CoAP Server Example is not working
Risposta
09/07/19 8.39 come risposta a Pedro Silva.

Hi 

The Application is updated on developer page and the issue is fixed .

Please visit the xdk developer page .

Thanks

+1 (1 Voto)