static void DoMessages()

in iothub_client/src/iothubtransporthttp.c [1906:2081]


static void DoMessages(HTTPTRANSPORT_HANDLE_DATA* handleData, HTTPTRANSPORT_PERDEVICE_DATA* deviceData)
{
    if (deviceData->DoWork_PullMessage)
    {
        time_t timeNow = get_time(NULL);
        bool isPollingAllowed = deviceData->isFirstPoll || (timeNow == (time_t)(-1)) || (get_difftime(timeNow, deviceData->lastPollTime) > handleData->getMinimumPollingTime);
        if (isPollingAllowed)
        {
            HTTP_HEADERS_HANDLE responseHTTPHeaders = HTTPHeaders_Alloc();
            if (responseHTTPHeaders == NULL)
            {
                LogError("unable to HTTPHeaders_Alloc");
            }
            else
            {
                BUFFER_HANDLE responseContent = BUFFER_new();
                if (responseContent == NULL)
                {
                    LogError("unable to BUFFER_new");
                }
                else
                {
                    unsigned int statusCode = 0;
                    HTTPAPIEX_RESULT r;
                    if (deviceData->deviceSasToken != NULL)
                    {
                        if (HTTPHeaders_ReplaceHeaderNameValuePair(deviceData->messageHTTPrequestHeaders, IOTHUB_AUTH_HEADER_VALUE, STRING_c_str(deviceData->deviceSasToken)) != HTTP_HEADERS_OK)
                        {
                            r = HTTPAPIEX_ERROR;
                            LogError("Unable to replace the old SAS Token.");
                        }
                        else if ((r = HTTPAPIEX_ExecuteRequest(
                            handleData->httpApiExHandle,
                            HTTPAPI_REQUEST_GET,                                            /*requestType: GET*/
                            STRING_c_str(deviceData->messageHTTPrelativePath),         /*relativePath: the message HTTP relative path*/
                            deviceData->messageHTTPrequestHeaders,                     /*requestHttpHeadersHandle: message HTTP request headers created by _Create*/
                            NULL,                                                           /*requestContent: NULL*/
                            &statusCode,                                                    /*statusCode: a pointer to unsigned int which shall be later examined*/
                            responseHTTPHeaders,                                            /*responseHeadearsHandle: a new instance of HTTP headers*/
                            responseContent                                                 /*responseContent: a new instance of buffer*/
                        )) != HTTPAPIEX_OK)
                        {
                            LogError("Unable to HTTPAPIEX_ExecuteRequest.");
                        }
                    }
                    else if ((r = HTTPAPIEX_SAS_ExecuteRequest(
                        deviceData->sasObject,
                        handleData->httpApiExHandle,
                        HTTPAPI_REQUEST_GET,                                            /*requestType: GET*/
                        STRING_c_str(deviceData->messageHTTPrelativePath),         /*relativePath: the message HTTP relative path*/
                        deviceData->messageHTTPrequestHeaders,                     /*requestHttpHeadersHandle: message HTTP request headers created by _Create*/
                        NULL,                                                           /*requestContent: NULL*/
                        &statusCode,                                                    /*statusCode: a pointer to unsigned int which shall be later examined*/
                        responseHTTPHeaders,                                            /*responseHeadearsHandle: a new instance of HTTP headers*/
                        responseContent                                                 /*responseContent: a new instance of buffer*/
                    )) != HTTPAPIEX_OK)
                    {
                        LogError("unable to HTTPAPIEX_SAS_ExecuteRequest");
                    }
                    if (r == HTTPAPIEX_OK)
                    {
                        /*HTTP dialogue was succesfull*/
                        if (timeNow == (time_t)(-1))
                        {
                            deviceData->isFirstPoll = true;
                        }
                        else
                        {
                            deviceData->isFirstPoll = false;
                            deviceData->lastPollTime = timeNow;
                        }
                        if (statusCode == 204)
                        {
                            /*this is an expected status code, means "no commands", but logging that creates panic*/

                            /*do nothing, advance to next action*/
                        }
                        else if (statusCode != 200)
                        {
                            LogError("expected status code was 200, but actually was received %u... moving on", statusCode);
                        }
                        else
                        {
                            const char* etagValue = HTTPHeaders_FindHeaderValue(responseHTTPHeaders, "ETag");
                            if (etagValue == NULL)
                            {
                                LogError("unable to find a received header called \"E-Tag\"");
                            }
                            else
                            {
                                size_t etagsize = strlen(etagValue);
                                if (
                                    (etagsize < 2) ||
                                    (etagValue[0] != '"') ||
                                    (etagValue[etagsize - 1] != '"')
                                    )
                                {
                                    LogError("ETag is not a valid quoted string");
                                }
                                else
                                {
                                    const unsigned char* resp_content;
                                    size_t resp_len;
                                    resp_content = BUFFER_u_char(responseContent);
                                    resp_len = BUFFER_length(responseContent);
                                    IOTHUB_MESSAGE_HANDLE receivedMessage = IoTHubMessage_CreateFromByteArray(resp_content, resp_len);
                                    bool abandon = false;
                                    if (receivedMessage == NULL)
                                    {
                                        LogError("unable to IoTHubMessage_CreateFromByteArray, trying to abandon the message... ");
                                        abandon = true;
                                    }
                                    else
                                    {
                                        if (retrieve_message_properties(responseHTTPHeaders, receivedMessage) != 0)
                                        {
                                            LogError("Failed retrieving message properties");
                                            abandon = true;
                                        }
                                        else
                                        {
                                            MESSAGE_DISPOSITION_CONTEXT* dispositionContext = CreateMessageDispositionContext(etagValue);

                                            if (dispositionContext == NULL)
                                            {
                                                LogError("failed to create disposition context");
                                                abandon = true;
                                            }
                                            else
                                            {
                                                if (IoTHubMessage_SetDispositionContext(receivedMessage, dispositionContext, DestroyMessageDispositionContext) != IOTHUB_MESSAGE_OK)
                                                {
                                                    LogError("Failed setting disposition context in IOTHUB_MESSAGE_HANDLE");
                                                    DestroyMessageDispositionContext(dispositionContext);
                                                    abandon = true;
                                                }
                                                else if (!handleData->transport_callbacks.msg_cb(receivedMessage, deviceData->device_transport_ctx))
                                                {
                                                    LogError("IoTHubClientCore_LL_MessageCallback failed");
                                                    abandon = true;
                                                }
                                            }
                                        }

                                        if (abandon)
                                        {
                                            // If IoTHubMessage_SetDispositionContext succeeds above, it transitions ownership of 
                                            // dispositionContext to the receivedMessage.
                                            // IoTHubMessage_Destroy() below will handle freeing it.
                                            IoTHubMessage_Destroy(receivedMessage);
                                        }
                                    }

                                    if (abandon)
                                    {
                                        if (!abandonOrAcceptMessage(handleData, deviceData, etagValue, IOTHUBMESSAGE_ABANDONED))
                                        {
                                            LogError("HTTP Transport layer failed to report ABANDON disposition");
                                        }
                                    }
                                }
                            }
                        }
                    }
                    BUFFER_delete(responseContent);
                }
                HTTPHeaders_Free(responseHTTPHeaders);
            }
        }
        else
        {
            /*isPollingAllowed is false... */
            /*do nothing "shall be ignored*/
        }
    }
}