SOCKET_SEND_RESULT socket_transport_send()

in win32/src/socket_transport_win32.c [410:474]


SOCKET_SEND_RESULT socket_transport_send(SOCKET_TRANSPORT_HANDLE socket_transport, const SOCKET_BUFFER* payload, uint32_t buffer_count, uint32_t* bytes_sent, uint32_t flags, void* overlapped_data)
{
    SOCKET_SEND_RESULT result;
    // Codes_SOCKET_TRANSPORT_WIN32_09_032: [ If socket_transport is NULL, socket_transport_send shall fail and return SOCKET_SEND_INVALID_ARG. ]
    if (socket_transport == NULL ||
        // Codes_SOCKET_TRANSPORT_WIN32_09_033: [ If payload is NULL, socket_transport_send shall fail and return SOCKET_SEND_INVALID_ARG. ]
        payload == NULL ||
        // Codes_SOCKET_TRANSPORT_WIN32_09_034: [ If buffer_count is 0, socket_transport_send shall fail and return SOCKET_SEND_INVALID_ARG. ]
        buffer_count == 0)
    {
        LogError("Invalid arguments: SOCKET_TRANSPORT_HANDLE socket_transport: %p, const SOCKET_BUFFER* payload: %p, void* overlapped_data: %p",
            socket_transport, payload, overlapped_data);
        result = SOCKET_SEND_INVALID_ARG;
    }
    else
    {
        // Codes_SOCKET_TRANSPORT_WIN32_09_035: [ socket_transport_send shall call sm_exec_begin. ]
        SM_RESULT sm_result = sm_exec_begin(socket_transport->sm);

        // Codes_SOCKET_TRANSPORT_WIN32_09_036: [ If sm_exec_begin does not return SM_EXEC_GRANTED, socket_transport_send shall fail and return SOCKET_SEND_ERROR. ]
        if (sm_result != SM_EXEC_GRANTED)
        {
            LogError("sm_exec_begin failed : %" PRI_MU_ENUM, MU_ENUM_VALUE(SM_RESULT, sm_result));
            result = SOCKET_SEND_ERROR;
        }
        else
        {
            DWORD num_bytes = 0;
            LPDWORD num_bytes_param = NULL;
            // If the overlapped is NULL then set the num bytes params
            if (overlapped_data == NULL)
            {
                num_bytes_param = &num_bytes;
            }

            int send_result;

            // Codes_SOCKET_TRANSPORT_WIN32_09_037: [ socket_transport_send shall call WSASend to send data with flags and the overlapped_data. ]
            send_result = WSASend(socket_transport->socket, (LPWSABUF)payload, buffer_count, num_bytes_param, flags, (LPWSAOVERLAPPED)overlapped_data, NULL);

            // Codes_SOCKET_TRANSPORT_WIN32_09_038: [ If WSASend returns 0, socket_transport_send shall store the bytes written in bytes_written (if non-NULL) and return SOCKET_SEND_OK. ]
            if (send_result == 0)
            {
#ifdef ENABLE_SOCKET_LOGGING
                LogVerbose("Send completed synchronously at %lf", timer_global_get_elapsed_us());
#endif
                if (bytes_sent != NULL)
                {
                    *bytes_sent = num_bytes;
                }
                result = SOCKET_SEND_OK;
            }
            // Codes_SOCKET_TRANSPORT_WIN32_09_039: [ Otherwise socket_transport_send shall return SOCKET_SEND_FAILED. ]
            else
            {
                LogLastError("Failure sending socket data: buffer: %p, length: %" PRIu32 "", payload->buffer, payload->length);
                result = SOCKET_SEND_FAILED;
            }

            // Codes_SOCKET_TRANSPORT_WIN32_09_040: [ socket_transport_send shall call sm_exec_end. ]
            sm_exec_end(socket_transport->sm);
        }
    }
    return result;
}