Coap Block-wise Block2 response to GET #9683
-
Hi Guys, My idea is to implement a Block2 response to the GET request but it seems not working. I took a look at the coap cli example (I'm writing in C so the porting is not 1 to 1) and, afaik the code is 100% similar but my server always return 5.00 as a reply. this is my handler for the GET request: static void _OHCS_WellKnownHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo){
//char buffer[MAX_WELLKNOWN_STRING_LEN]; // Let's use the stack and not the heap... is there a reason why?
oh_coap_server_context_t * srv_ctx = (oh_coap_server_context_t *)aContext;
otMessage *response;
otError err;
otCoapOptionIterator iterator;
bool blockPresent = false;
uint64_t blockValue = OT_COAP_OPTION_BLOCK_SZX_128;
otCoapType type = otCoapMessageGetType(aMessage);
otCoapCode code = otCoapMessageGetCode(aMessage);
LOG_INF("Well known requested!");
if(srv_ctx->wk_core_lnk == NULL){
LOG_INF("Allocating memory...");
srv_ctx->wk_core_lnk = malloc(2048);
if(srv_ctx->wk_core_lnk == NULL){
LOG_ERR("Unable to allocate 4k of memory");
return;
}
memset(srv_ctx->wk_core_lnk, 0, 2048);
_OHCS_GetWellKnownString(srv_ctx, srv_ctx->wk_core_lnk, NULL);
LOG_INF("Lenght of WK is %d", strlen(srv_ctx->wk_core_lnk));
srv_ctx->wk_core_lnk = realloc(srv_ctx->wk_core_lnk, strlen(srv_ctx->wk_core_lnk) + 1);
}else{
LOG_INF("Memory for buffer already allocated...");
}
if(type != OT_COAP_TYPE_CONFIRMABLE){
//return;
}
if(code != OT_COAP_CODE_GET){
return;
}
err = otCoapOptionIteratorInit(&iterator, aMessage);
if(_OHCS_PrintError(err)){
return;
}
if (otCoapOptionIteratorGetFirstOptionMatching(&iterator, OT_COAP_OPTION_BLOCK2) != NULL)
{
err = otCoapOptionIteratorGetOptionUintValue(&iterator, &blockValue);
if(_OHCS_PrintError(err)){
return;
}
blockPresent = true;
}
LOG_DBG("Creating new message...");
response = otCoapNewMessage(OT_IN, NULL);
if(response == NULL){
LOG_ERR("Unable to create response oject");
return;
}
LOG_DBG("Initializing the message...");
err = otCoapMessageInitResponse(response, aMessage, type, OT_COAP_CODE_CONTENT);
if(_OHCS_PrintError(err)){
otMessageFree(response);
return;
}
err = otCoapMessageAppendContentFormatOption(response, OT_COAP_OPTION_CONTENT_FORMAT_LINK_FORMAT);
if (err != OT_ERROR_NONE){
LOG_ERR("Unable to set content option: %s", otThreadErrorToString(err));
}
LOG_DBG("Populating buffer");
if (strlen(srv_ctx->wk_core_lnk) > BLK_SIZE){
LOG_INF("As far as it seems resoursce string is longer than %d, adding Block2 option", BLK_SIZE);
err = otCoapMessageAppendBlock2Option(response, (uint32_t)(blockValue >> 4), true,
(otCoapBlockSzx)(blockValue & 0x7));
if(err != OT_ERROR_NONE){
LOG_ERR("Unable to add option %s", otThreadErrorToString(err));
}
}
LOG_DBG("Setting the payload marker...");
err = otCoapMessageSetPayloadMarker(response);
if(err != OT_ERROR_NONE){
LOG_ERR("Unable to set payload marker: %s", otThreadErrorToString(err));
otMessageFree(response);
return;
}
if (strlen(srv_ctx->wk_core_lnk) > BLK_SIZE){
// Send block2
if(type == OT_COAP_TYPE_CONFIRMABLE){
LOG_WRN("Block2 operations is not allowed for CON packages");
}
LOG_INF("Sending response with blockwise...");
err = otCoapSendResponseBlockWise(OT_IN, response, aMessageInfo, srv_ctx, _OHCS_WKTxHook);
_OHCS_PrintError(err);
}else{
LOG_DBG("Appending buffer to payload...");
err = otMessageAppend(response, srv_ctx->wk_core_lnk, strlen(srv_ctx->wk_core_lnk));
if(err != OT_ERROR_NONE){
LOG_ERR("Unable to append payload: %s", otThreadErrorToString(err));
otMessageFree(response);
return;
}
LOG_DBG("Sending response...");
err = otCoapSendResponse(OT_IN, response, aMessageInfo);
}
if(err != OT_ERROR_NONE){
LOG_ERR("Unable to send response: %s", otThreadErrorToString(err));
otMessageFree(response);
return;
}
LOG_INF("Response function finished");
} and this is my tx hook: otError _OHCS_WKTxHook(void *aContext,
uint8_t *aBlock,
uint32_t aPosition,
uint16_t *aBlockLength,
bool *aMore){
oh_coap_server_context_t *srv_ctx = (oh_coap_server_context_t *) aContext;
LOG_INF("Getting posisition at %d", aPosition);
size_t index = aPosition - *aBlockLength;
LOG_INF("Getting posisition at %d", index);
memcpy(aBlock, &srv_ctx->wk_core_lnk[index], *aBlockLength);
if(index + *aBlockLength > strlen(srv_ctx->wk_core_lnk)){
LOG_INF("NOT needing other block after this one");
*aMore = false;
}else{
LOG_INF("Need other block after this one");
*aMore = true;
}
//otRandomNonCryptoFillBuffer
return OT_ERROR_NONE;
} The principle is quite simple: If the Well-known string can fit in a packet it send it as a single reply, if it cannot it enable the Block2 option. The output from the logs on the serial port is:
And then I get a 5.00 on the client and no data... Do you have any idea? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Ok, nevermind, going deep in the code I set the wrong message type. It need to be |
Beta Was this translation helpful? Give feedback.
Ok, nevermind, going deep in the code I set the wrong message type. It need to be
OT_COAP_TYPE_ACKNOWLEDGMENT
to keep track of the response...