CoAP Server Example is not working
응답
19. 6. 13 오전 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 투표)
RE: CoAP Server Example is not working
응답
19. 6. 19 오전 9:03 as a reply to Pedro Silva.

hi Pedro

We are looking into this ..

Will get back to you shortly

Thanks

Priyashi

0 (0 투표)
RE: CoAP Server Example is not working
응답
19. 6. 19 오전 10:59 as a reply to 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 투표)
RE: CoAP Server Example is not working
응답
19. 6. 19 오전 11:38 as a reply to 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 투표)
RE: CoAP Server Example is not working
응답
19. 6. 21 오전 9:18 as a reply to 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 투표)
RE: CoAP Server Example is not working
응답
19. 6. 25 오전 10:16 as a reply to 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 투표)
RE: CoAP Server Example is not working
응답
19. 6. 26 오전 4:13 as a reply to 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

0 (0 투표)