lobaro / lobaro-coap

CoAP Implementation in C
MIT License
124 stars 47 forks source link

Observe in client is not working #25

Open baw-benji opened 6 years ago

baw-benji commented 6 years ago

Description

The client is requesting correctly with the observe option and getting an ACK from the server. But after the first CON from the server my callback (sendRequestCB) is called and the interaction is getting deleted. (@see: coap_main.c:handleClientInteraction) In return the client sends a RST instead of an ACK because he cannot find the previous deleted interaction. (@see: coap_main.c:CoAP_HandleIncomingPacket) The server removes the subscriber because he received a RST (Cancel Observation).

Client code

CoAP_Result_t res = CoAP_StartNewGetObserveRequest_my("din0", mCoapSocket->Handle, &mReceiver, sendRequestCB);

CoAP_Result_t CoapClient::sendRequestCB(CoAP_Message_t* pRespMsg, NetEp_t* Sender) {
    printf("--------------------------------->>>>> sendRequestCB done\n");
    ...
}

CoAP_Result_t _rom CoapClient::CoAP_StartNewGetObserveRequest_my(char* UriString, SocketHandle_t socketHandle, NetEp_t* ServerEp, CoAP_RespHandler_fn_t cb) {
    CoAP_Message_t* pReqMsg = CoAP_CreateMessage(CON, REQ_GET, CoAP_GetNextMid(), NULL, 0, 0, CoAP_GenerateToken());
    if (pReqMsg != NULL) {
        CoAP_AppendUriOptionsFromString(&(pReqMsg->pOptionsList), UriString);
        AddObserveOptionToMsg(pReqMsg, 0);
        CoAP_blockwise_option_t blkOption;
        blkOption.Type = BLOCK_2;
        blkOption.BlockSize = BLOCK_SIZE_64;
        blkOption.MoreFlag = 0;
        blkOption.BlockNum = 0;
        AddBlkOptionToMsg(pReqMsg, &blkOption);
        return CoAP_StartNewClientInteraction(pReqMsg, socketHandle, ServerEp, cb);
    }

    INFO("- New GetRequest failed: Out of Memory\r\n");
    return COAP_ERR_OUT_OF_MEMORY;
}
nzfarmer commented 6 years ago

I found our version (slightly early than the tip) also was not working and have added a hack to get us over the line. See below. After the handler is invoked, we check to ensure it is not observable before deleting the interaction:

coap_main.c:620 (Just after calling Handler!)

                    // Add support for Client based requests with the Observer option
                    // Check if response has the Observe flag, and reset state.
                    // Ensure we don't remove original Request as it is required for token comparison!
                    if ((GetObserveOptionFromMsg(pIA->pRespMsg,&obsVal) == COAP_OK) && obsVal > 0) 
                     {
                       pIA->State              = COAP_STATE_WAITING_RESPONSE;
                       pIA->pReqMsg->Type      = NON;
                       pIA->pReqMsg->Timestamp = hal_rtc_1Hz_Cnt();
                       RemoveObserveOptionFromMsg(pIA->pRespMsg);
                       CoAP_SetSleepInteraction(pIA, POSTPONE_WAIT_TIME_SEK);
                       CoAP_EnqueueLastInteraction(pIA);
                    } else {
                       CoAP_DeleteInteraction(pIA); //direct delete, todo: eventually wait some time to send ACK instead of RST if out ACK to remote reponse was lost
                    }
srikumaresan commented 2 years ago

Was this ever resolved? I seem to be having the same issue still today.

baw-benji commented 2 years ago

No not to my knowledge. I'm using the workaround suggested by @nzfarmer .