/*
 *
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include "nlassert.h"
#include "nlweavebdxserver.h"
#include <unistd.h>
#include <fcntl.h>

namespace nl {
namespace Weave {
namespace Profiles {

BulkDataTransferServer::BulkDataTransferServer()
{
    ExchangeMgr = NULL;
    mpAppState = NULL;
    OnBDXReceiveInitRequestReceived = NULL;
    OnBDXBlockQueryRequestReceived = NULL;
    OnBDXBlockEOFAckReceived = NULL;
    OnBDXTransferFailed = NULL;
    OnBDXTransferSucceeded = NULL;
}

BulkDataTransferServer::~BulkDataTransferServer()
{
    Shutdown();
}

WEAVE_ERROR BulkDataTransferServer::Init(WeaveExchangeManager *exchangeMgr, void *appState,
        const char *hostedFileName, const char *receivedFileLocation)
{
    // Error if already initialized.
    if (ExchangeMgr != NULL)
        return WEAVE_ERROR_INCORRECT_STATE;

    ExchangeMgr = exchangeMgr;
    mpAppState = appState;
    mHostedFileName = hostedFileName;
    mReceivedFileLocation = receivedFileLocation;

    // Initialize connection pool
    memset(mTransferPool, 0, sizeof(mTransferPool));
    for (int i = 0; i < MAX_NUM_BDX_TRANSFERS; i++)
    {
        mTransferPool[i].FD = -1;
    }

    // Register to receive unsolicited ReceiveInitiation messages from the exchange manager.
    ExchangeMgr->RegisterUnsolicitedMessageHandler(kWeaveProfile_BDX, kMsgType_ReceiveInit, HandleReceiveInitRequest, this);
    ExchangeMgr->RegisterUnsolicitedMessageHandler(kWeaveProfile_BDX, kMsgType_SendInit, HandleSendInitRequest, this);

    return WEAVE_NO_ERROR;
}

WEAVE_ERROR BulkDataTransferServer::Shutdown()
{
    printf("0 BDX Shutdown entering\n");

    if (ExchangeMgr != NULL)
    {
        // Shutdown actions to perform only if BDX server initialized:

        ExchangeMgr->UnregisterUnsolicitedMessageHandler(kWeaveProfile_BDX, kMsgType_ReceiveInit);
        ExchangeMgr->UnregisterUnsolicitedMessageHandler(kWeaveProfile_BDX, kMsgType_SendInit);
        ExchangeMgr = NULL;

        // Explicitly shut down transfers to free any held Weave resources
        for (int i = 0; i < MAX_NUM_BDX_TRANSFERS; i++)
        {
            ShutdownTransfer(&mTransferPool[i], true);
        }
    }

    // Shutdown actions to perform even if BDX server uninitialized:

    mpAppState = NULL;
    OnBDXReceiveInitRequestReceived = NULL;
    OnBDXBlockQueryRequestReceived = NULL;
    OnBDXBlockEOFAckReceived = NULL;
    OnBDXTransferFailed = NULL;
    OnBDXTransferSucceeded = NULL;

    printf("1 BDX Shutdown exiting\n");
    return WEAVE_NO_ERROR;
}

BulkDataTransferServer::BDXTransfer *BulkDataTransferServer::NewTransfer()
{
    for (int i = 0; i < MAX_NUM_BDX_TRANSFERS; i++)
    {
        if (!mTransferPool[i].BdxApp)
        {
            mTransferPool[i].BdxApp = this;
            return &mTransferPool[i];
        }
    }

    return NULL;
}

void BulkDataTransferServer::ShutdownTransfer(BDXTransfer *xfer, bool closeCon)
{
    if (xfer->BdxApp == NULL)
    {
        // Suppress log spew if iterating through entire connection pool as part of Shutdown()
        return;
    }

    printf("0 BDX ShutdownTransfer entering\n");
    uint64_t peerNodeId = kNodeIdNotSpecified;
    IPAddress peerAddr = IPAddress::Any;

    // Get values to send application callback
    if (xfer->EC && xfer->EC->Con)
    {
        peerNodeId = xfer->EC->Con->PeerNodeId;
        peerAddr = xfer->EC->Con->PeerAddr;
    }

    // Fire application callback
    if (false == xfer->CompletedSuccessfully)
    {
        if (OnBDXTransferFailed)
        {
            OnBDXTransferFailed(peerNodeId, peerAddr, mpAppState);
        }
    }
    else
    {
        if (OnBDXTransferSucceeded)
        {
            OnBDXTransferSucceeded(peerNodeId, peerAddr, mpAppState);
        }
    }

    /* Reset and release transfer object. This needs to be done before the Weave connection
       is closed because closing a Weave connection will call EC->OnConnectionClosed which in turn will
       call our OnConnectionClosed handler which will then call ShutdownTranser() again.
       Because xfer->BdxApp is NULL the second time ShutdownTranser() is called it will exit right away */

    xfer->MaxBlockSize = 0;
    xfer->CompletedSuccessfully = false;
    xfer->BdxApp = NULL;

    // Release Weave resources
    if (xfer->EC)
    {
        printf("1 BDX ShutdownTransfer closing EC\n");

        if (closeCon && xfer->EC->Con)
        {
            printf("2 BDX ShutdownTransfer closing Con\n");
            xfer->EC->Con->Close();
            xfer->EC->Con = NULL;
        }

        xfer->EC->Close();
        xfer->EC = NULL;
    }

    // Close file
    if (xfer->FD != -1)
    {
        printf("4 BDX ShutdownTransfer closing FD\n");
        close(xfer->FD);
        xfer->FD = -1;
    }

    printf("5 BDX ShutdownTransfer exiting");
}

void BulkDataTransferServer::HandleReceiveInitRequest(ExchangeContext *ec, const IPPacketInfo *packetInfo,
        const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payloadReceiveInit)
{
    // We're guaranteed of the right message profile and type by the ExchangeMgr.
    printf("0 BDX HandleReceiveInitRequest entering\n");

    WEAVE_ERROR ret = WEAVE_NO_ERROR;
    const uint8_t BDX_SERVER_TRANSFER_MODE = 0x02U; //ASYNC==0, RDRIVE==1, SDRIVE==0
    BulkDataTransferServer *bdxApp = NULL;
    BDXTransfer *xfer = NULL;
    PacketBuffer *payload = NULL;
    char *fileDesignator = NULL;

    ReceiveAccept receiveAccept;
    ReceiveReject receiveReject;
    ReceiveInit   receiveInit;

    nlREQUIRE_ACTION(ec != NULL, handle_receive_init_request_failed,
                     printf("0.5 BDX HandleReceiveInitRequest failed, null EC\n"));
    bdxApp = (BulkDataTransferServer *) ec->AppState;

    // Parse init request and discard payload buffer
    ret = ReceiveInit::parse(payloadReceiveInit, receiveInit);
    nlREQUIRE(ret == WEAVE_NO_ERROR, handle_receive_init_request_failed);
    PacketBuffer::Free(payloadReceiveInit);
    payloadReceiveInit = NULL;

    // Grab BDXTransfer object for this transfer
    xfer = bdxApp->NewTransfer();

    if (!xfer)
    {
        printf("1 BDX HandleReceiveInitRequest (transfer alloc failed)\n");
        SendTransferError(ec, kWeaveProfile_Common, kStatus_OutOfMemory);
        goto handle_receive_init_request_failed;
    }

    // Hang new BDXTransfer on exchange context
    ec->AppState = xfer;

    // Initialize xfer struct (move to init function?)
    xfer->EC = ec;
    xfer->FD = -1; // memset(0) doesn't set us up for ShutdownTransfer()

    if (receiveInit.theMaxBlockSize <= 0) {
        printf("2 BDX HandleReceiveInitRequest (maxBlockSize <= 0)\n");

        // Send rejection status message
        receiveReject.init(kWeaveProfile_Common, kStatus_BadRequest);
        if ((payload = PacketBuffer::New()) == NULL)
        {
            printf("2.5 BDX HandleReceiveInitRequest (PacketBuffer alloc failed)\n");
            goto handle_receive_init_request_failed;
        }

        receiveReject.pack(payload);
        ret = ec->SendMessage(kWeaveProfile_Common, kMsgType_ReceiveReject, payload);
        payload = NULL;
        if (ret != WEAVE_NO_ERROR)
        {
            printf("3 BDX HandleReceiveInitRequest err=%d\n", ret);
        }
        goto handle_receive_init_request_failed;

    }
    xfer->MaxBlockSize  = receiveInit.theMaxBlockSize;

    if (receiveInit.theFileDesignator.theLength <= 0) {
        printf("4 BDX HandleReceiveInitRequest (bad FileDesignator)\n");
        SendTransferError(ec, kWeaveProfile_Common, kStatus_LengthTooShort);
        goto handle_receive_init_request_failed;
    }

    // Copy file name onto C-string
    // NOTE: the original string is not NUL terminated, but we know its length.
    fileDesignator = (char*)malloc(1 + receiveInit.theFileDesignator.theLength);
    memcpy(fileDesignator, receiveInit.theFileDesignator.theString, receiveInit.theFileDesignator.theLength);
    fileDesignator[receiveInit.theFileDesignator.theLength] = '\0';

    // TODO Validate requested file path with value from nlhlfirmware.plist
    // Future: delegate path security validation
    // nlclient will open() this path as root, so we must be conservative in our validation.
    if (0 != strcmp(fileDesignator, bdxApp->mHostedFileName))
    {
        printf("5 BDX HandleReceiveInitRequest (forbidden FileDesignator)\n");
        SendTransferError(ec, kWeaveProfile_Common, kStatus_UnknownFile); //TODO add 'forbidden' Weave status code
        free(fileDesignator);
        fileDesignator = NULL;
        goto handle_receive_init_request_failed;
    }

    // Open file to send
    xfer->FD = open(fileDesignator, O_RDONLY);
    free(fileDesignator);
    fileDesignator = NULL;

    if (xfer->FD == -1)
    {
        printf("6 BDX HandleReceiveInitRequest (open FAIL)\n");
        SendTransferError(ec, kWeaveProfile_Common, kStatus_InternalServerProblem);
        goto handle_receive_init_request_failed;
    }

    // Send a ReceiveAccept response back to the receiver.
    printf("7 BDX HandleReceiveInitRequest validated request\n");

    // Fire application callback once we've validated the request (TODO: call earlier? feels like semantic abuse)
    if (bdxApp->OnBDXReceiveInitRequestReceived)
    {
        bdxApp->OnBDXReceiveInitRequestReceived(ec->PeerNodeId, ec->PeerAddr, payloadReceiveInit, bdxApp->mpAppState);
    }

    // Set up response timeout and connection closed handler
    ec->Con->AppState = xfer;
    ec->OnConnectionClosed = HandleBDXConnectionClosed;
    ec->OnResponseTimeout = HandleResponseTimeout;
    ec->ResponseTimeout = BDX_RESPONSE_TIMEOUT_MS;

    // Set ourselves up to handle first BlockQueryRequest.
    ec->OnMessageReceived = HandleBlockQueryRequest;

    receiveAccept.init(BDX_SERVER_TRANSFER_MODE, receiveInit.theMaxBlockSize, receiveInit.theLength, NULL);
    if ((payload = PacketBuffer::New()) == NULL)
    {
        printf("7.5 BDX HandleReceiveInitRequest (PacketBuffer alloc failed)\n");
        goto handle_receive_init_request_failed;
    }

    receiveAccept.theMaxBlockSize = receiveInit.theMaxBlockSize;
    ret = receiveAccept.pack(payload);
    nlREQUIRE(ret == WEAVE_NO_ERROR, handle_receive_init_request_failed);

    ret = ec->SendMessage(kWeaveProfile_BDX, kMsgType_ReceiveAccept, payload, ExchangeContext::kSendFlag_ExpectResponse);
    payload = NULL;
    if (ret != WEAVE_NO_ERROR)
    {
        printf("8 BDX HandleReceiveInitRequest err=%d\n", ret);
        goto handle_receive_init_request_failed;
    }

    printf("9 BDX HandleReceiveInitRequest exiting (success)\n");
    return;

handle_receive_init_request_failed:
    printf("10 BDX HandleReceiveInitRequest exiting (failure)\n");

    if (payload)
    {
        PacketBuffer::Free(payload);
        payload = NULL;
    }

    if (payloadReceiveInit)
    {
        PacketBuffer::Free(payloadReceiveInit);
        payloadReceiveInit = NULL;
    }

    if (xfer)
    {
        bdxApp->ShutdownTransfer(xfer, true);
    }
    else
    {
        // Transfer object uninitialized, so we do this manually
        if (ec)
        {
            if (ec->Con)
            {
                ec->Con->Close();
                ec->Con = NULL;
            }

            ec->Close();
            ec = NULL;
        }
    }
}

void BulkDataTransferServer::HandleSendInitRequest(ExchangeContext *ec, const IPPacketInfo *packetInfo, const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payload)
{
    printf("BDX HandleSendInitRequest entering\n");

    WEAVE_ERROR err = WEAVE_NO_ERROR;
    BulkDataTransferServer *bdxApp = NULL;
    BDXTransfer *xfer = NULL;

    SendInit sendInit;
    SendAccept sendAccept;
    SendReject sendReject;

    char *filename = NULL;
    char *filename_buf = NULL;
    size_t filename_len = 0;
    size_t received_location_len = 0;
    uint8_t offset = 0;
    char *destination_filename = NULL;
    PacketBuffer *SendInitResponsePayload = NULL;

    nlREQUIRE(ec, handle_send_init_request_failed);
    bdxApp = static_cast<BulkDataTransferServer *>(ec->AppState);

    xfer = bdxApp->NewTransfer();
    nlREQUIRE(xfer, handle_send_init_request_failed);

    xfer->EC = ec;
    xfer->FD = -1;
    xfer->CompletedSuccessfully = false;
    ec->AppState = (void*)xfer;

    err = SendInit::parse(payload, sendInit);
    nlREQUIRE(err == WEAVE_NO_ERROR, handle_send_init_request_failed);

    xfer->MaxBlockSize = sendInit.theMaxBlockSize;
    PacketBuffer::Free(payload);
    payload = NULL;

    // Allocate PacketBuffer
    SendInitResponsePayload = PacketBuffer::New();
    nlREQUIRE_ACTION(SendInitResponsePayload != NULL, handle_send_init_request_failed,
                         printf("Error: BDX HandleSendInitRequest: PacketBuffer alloc failed\n"));

    // Copy out the name of the file being received to a NULL-terminated string
    filename_buf = strndup(sendInit.theFileDesignator.theString, sendInit.theFileDesignator.theLength);
    nlREQUIRE(filename_buf != NULL, handle_send_init_request_failed);

    printf("sendInit.theFileDesignator: %s\n", filename_buf);

    // In case the file name is a path, keep only the file name;
    // the file will be saved in bdxApp->mReceivedFileLocation.
    filename = strrchr(filename_buf, '/');
    if (filename == NULL)
    {
        filename = filename_buf;
    }
    else
    {
        filename++; //skip over '/'
    }

    filename_len = strlen(filename);

    received_location_len = strlen(bdxApp->mReceivedFileLocation);

    // malloc enough space for the NULL terminator and a '/'
    destination_filename = (char*)malloc(received_location_len + filename_len + 2);
    nlREQUIRE(destination_filename != NULL, handle_send_init_request_failed);

    memcpy(destination_filename, bdxApp->mReceivedFileLocation, received_location_len);
    if (bdxApp->mReceivedFileLocation[received_location_len - 1] != '/')
    {
        // if it doesn't end with '/', add one
        destination_filename[received_location_len] = '/';
        offset++;
    }
    memcpy(destination_filename + received_location_len + offset, filename, filename_len);
    destination_filename[received_location_len + offset + filename_len] = '\0';

    printf("File being saved to: %s\n", destination_filename);
    xfer->FD = open(destination_filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
    free(destination_filename);
    destination_filename = NULL;
    free(filename_buf);
    filename_buf = NULL;

    if (xfer->FD == -1)
    {
        printf("Couldn't open file for writing...\n");

        err = sendReject.init(kWeaveProfile_BDX, kStatus_UnknownFile);
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_send_init_request_failed);

        err = sendReject.pack(SendInitResponsePayload);
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_send_init_request_failed);

        err = ec->SendMessage(kWeaveProfile_BDX, kMsgType_SendReject, SendInitResponsePayload, ExchangeContext::kSendFlag_ExpectResponse);
        SendInitResponsePayload = NULL;
        goto handle_send_init_request_failed;
    }

    // Finish up configuring and then send the SendInitResponse message
    sendAccept.theMaxBlockSize = xfer->MaxBlockSize;
    err = sendAccept.init(kMode_SenderDrive, xfer->MaxBlockSize, NULL);
    nlREQUIRE(err == WEAVE_NO_ERROR, handle_send_init_request_failed);

    err = sendAccept.pack(SendInitResponsePayload);
    nlREQUIRE(err == WEAVE_NO_ERROR, handle_send_init_request_failed);

    ec->OnMessageReceived = HandleBlockSend;

    err = ec->SendMessage(kWeaveProfile_BDX, kMsgType_SendAccept, SendInitResponsePayload,
                          ExchangeContext::kSendFlag_ExpectResponse);
    SendInitResponsePayload = NULL;
    nlREQUIRE_ACTION(err == WEAVE_NO_ERROR, handle_send_init_request_failed,
                 printf("SendInitResponse error sending accept message: %d", err));

    return;

handle_send_init_request_failed:

    if (filename_buf)
    {
        free(filename_buf);
        filename_buf = NULL;
    }

    if (destination_filename)
    {
        free(destination_filename);
        destination_filename = NULL;
    }

    printf("BDX HandleSendInitRequest exiting (failure)\n");

    if (SendInitResponsePayload)
    {
        PacketBuffer::Free(SendInitResponsePayload);
        SendInitResponsePayload = NULL;
    }

    if (payload)
    {
        PacketBuffer::Free(payload);
        payload = NULL;
    }

    if (xfer)
    {
        bdxApp->ShutdownTransfer(xfer, true);
    }
    else
    {
        // Transfer object uninitialized, so we do this manually
        if (ec)
        {
            if (ec->Con)
            {
                ec->Con->Close();
                ec->Con = NULL;
            }

            ec->Close();
            ec = NULL;
        }
    }
}

void BulkDataTransferServer::HandleBlockSend(ExchangeContext *ec, const IPPacketInfo *packetInfo, const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payload)
{
    printf("BDX HandleBlockSend entering\n");

    WEAVE_ERROR err = WEAVE_NO_ERROR;

    int len = 0;

    BlockSend blockSend;
    BDXTransfer *xfer = static_cast<BDXTransfer *>(ec->AppState);
    BulkDataTransferServer *bdxApp = xfer->BdxApp;
    PacketBuffer* ackPayload = PacketBuffer::New();

    // Parse message data to get the block counter later
    err = BlockSend::parse(payload, blockSend);
    //NOTE: we skip over the block counter so it doesn't appear in the file
    len = write(xfer->FD, blockSend.theData + sizeof(blockSend.theBlockCounter),
                     blockSend.theLength - sizeof(blockSend.theBlockCounter));
    PacketBuffer::Free(payload);
    payload = NULL;

    nlREQUIRE_ACTION(len >= 0, handle_block_send_failed,
                 printf("Error: HandleBlockSend: Unable to read image into block\n"));

    // Always need to ACK a BlockEOF
    if (msgType == kMsgType_BlockEOF)
    {
        printf("Sending BlockEOFAck");

        BlockEOFAck blockEOFAck;
        nlREQUIRE_ACTION(ackPayload, handle_block_send_failed,
                         err = WEAVE_ERROR_NO_MEMORY;
                         printf("Error: BDX HandleBlockSend: PacketBuffer alloc failed\n"));

        err = blockEOFAck.init(blockSend.theBlockCounter-1); //final ack uses same block-counter of last block-query request
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_block_send_failed);

        err = blockEOFAck.pack(ackPayload);
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_block_send_failed);

        err = ec->SendMessage(kWeaveProfile_BDX, kMsgType_BlockEOFAck, ackPayload);
        ackPayload = NULL;
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_block_send_failed);

        bdxApp->ShutdownTransfer(xfer, true);
    }

    // currently we only support synchronous mode, so send BlockAck
    else {
        printf("Sending BlockAck\n");

        BlockAck blockAck;
        nlREQUIRE_ACTION(ackPayload, handle_block_send_failed,
                         err = WEAVE_ERROR_NO_MEMORY;
                         printf("Error: BDX HandleBlockSend: PacketBuffer alloc failed\n"));

        err = blockAck.init(blockSend.theBlockCounter);
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_block_send_failed);

        err = blockAck.pack(ackPayload);
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_block_send_failed);

        err = ec->SendMessage(kWeaveProfile_BDX, kMsgType_BlockAck, ackPayload);
        ackPayload = NULL;
        nlREQUIRE(err == WEAVE_NO_ERROR, handle_block_send_failed);
    }

handle_block_send_failed:

    if (err != WEAVE_NO_ERROR)
    {
        bdxApp->ShutdownTransfer(xfer, true);
    }

    if (ackPayload != NULL)
    {
        PacketBuffer::Free(ackPayload);
        ackPayload = NULL;
    }

    printf("HandleBlockSend exiting");
    return;
}

static int read_n(int fd, char *buf, int n)
{
    int nread, left = n;

    printf("0 read_n entering\n");

    while (left > 0)
    {
        printf("1 read_n (left: %d)\n", left);

        if ((nread = read(fd, buf, left)) > 0)
        {
            left -= nread;
            buf += nread;
            printf("2 read_n (nread: %d, left: %d)\n", nread, left);
        }
        else
        {
            printf("3 read_n (nread: 0, left: %d)\n", left);
            return n - left;
        }
    }

    printf("4 read_n (n: %d, left: %d) exiting\n", n, left);
    return n;
}

void BulkDataTransferServer::HandleBlockQueryRequest(ExchangeContext *ec, const IPPacketInfo *packetInfo,
        const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payloadBlockQuery)
{
    printf("0 BDX HandleBlockQueryRequest entering\n");
    WEAVE_ERROR ret = WEAVE_NO_ERROR;
    char *block = NULL;
    int len = 0;

    BlockQuery blockQuery;
    BDXTransfer *xfer = (BDXTransfer* ) ec->AppState;
    BulkDataTransferServer *bdxApp = xfer->BdxApp;
    PacketBuffer *responseBuf = NULL;

    // Parse message data to get the block counter later
    BlockQuery::parse(payloadBlockQuery, blockQuery);

    PacketBuffer::Free(payloadBlockQuery);
    payloadBlockQuery = NULL;

    if (kWeaveProfile_BDX != profileId ||  kMsgType_BlockQuery != msgType)
    {
        printf("1 BDX HandleBlockQueryRequest bad msg type (%d, %d)\n", profileId, msgType);
        SendTransferError(ec, kWeaveProfile_Common, kStatus_BadRequest);
        goto handle_block_query_request_failed;
    }

    if ((responseBuf = PacketBuffer::New()) == NULL)
    {
        printf("2 BDX HandleBlockQueryRequest (PacketBuffer alloc failed)\n");
        SendTransferError(ec, kWeaveProfile_Common, kStatus_InternalServerProblem);
        goto handle_block_query_request_failed;
    }

    printf("3 BDX HandleBlockQueryRequest (xfer->FD: %d)\n", xfer->FD);

    block = (char *) responseBuf->Start();
    *block = blockQuery.theBlockCounter;
    len = read_n(xfer->FD, block + 1, xfer->MaxBlockSize);

    if (len == xfer->MaxBlockSize)
    {
        printf("4 BDX HandleBlockQueryRequest (len = %d)\n", len);
        responseBuf->SetDataLength((uint16_t) len + 1);

        // Prepare to handle next BlockQueryRequest.
        ec->OnMessageReceived = HandleBlockQueryRequest;

        // Send a BlockSend Response back to the sender.
        ret = ec->SendMessage(kWeaveProfile_BDX, kMsgType_BlockSend, responseBuf, ExchangeContext::kSendFlag_ExpectResponse);
        responseBuf = NULL;
        if (ret != WEAVE_NO_ERROR)
        {
            printf("5 BDX HandleBlockQueryRequest (SendMessage failed, err=%d)\n", ret);
            goto handle_block_query_request_failed;
        }
    }
    else if ((len >= 0) && (len < xfer-> MaxBlockSize))
    {
        printf("6 BDX HandleBlockQueryRequest (len == 0)\n");

        // At EOF, so send empty payload.
        responseBuf->SetDataLength((uint16_t) len + 1);

        // Prepare to handle BlockEOF ACK.
        ec->OnMessageReceived = HandleBlockEOFAck;

        // Send a BlockEOF Response back to the sender.
        ret = ec->SendMessage(kWeaveProfile_BDX, kMsgType_BlockEOF, responseBuf, ExchangeContext::kSendFlag_ExpectResponse);
        responseBuf = NULL;
        if (ret != WEAVE_NO_ERROR)
        {
            printf("7 BDX HandleBlockQueryRequest\n");
            goto handle_block_query_request_failed;
        }
    }
    else
    {
        printf("8 BDX HandleBlockQueryRequest read failed (len < 0)\n");
        // read() failed
        SendTransferError(ec, kWeaveProfile_Common, kStatus_InternalServerProblem);
        goto handle_block_query_request_failed;
    }

    printf("9 BDX HandleBlockQueryRequest exiting (success)\n");
    return;

handle_block_query_request_failed:
    printf("10 BDX HandleBlockQueryRequest exiting (failure)\n");
    bdxApp->ShutdownTransfer(xfer, true);

    if (responseBuf)
    {
        PacketBuffer::Free(responseBuf);
        responseBuf = NULL;
    }
}

void BulkDataTransferServer::HandleBlockEOFAck(ExchangeContext *ec, const IPPacketInfo *packetInfo,
        const WeaveMessageInfo *msgInfo, uint32_t profileId, uint8_t msgType, PacketBuffer *payload)
{
    printf("0 BDX HandleBlockEOFAck entering\n");
    BDXTransfer *xfer = (BDXTransfer* ) ec->AppState;
    BulkDataTransferServer *bdxApp = xfer->BdxApp;

    // Free unused query payload.
    PacketBuffer::Free(payload);
    payload = NULL;

    if (kWeaveProfile_BDX != profileId ||  kMsgType_BlockEOFAck != msgType)
    {
        printf("1 BDX HandleBlockEOFAck bad msg type (%d, %d)\n", profileId, msgType);
        SendTransferError(ec, kWeaveProfile_Common, kStatus_BadRequest);
    }
    else
    {
        // Set flag for connection closed handler
        xfer->CompletedSuccessfully = true;

        // Fire application callback
        if (bdxApp->OnBDXBlockEOFAckReceived)
        {
            bdxApp->OnBDXBlockEOFAckReceived(ec->PeerNodeId, ec->PeerAddr, payload, bdxApp->mpAppState);
        }
    }

    // Either way it's the end of the line
    bdxApp->ShutdownTransfer(xfer, true);

    printf("2 BDX HandleBlockEOFAck exiting\n");
}

void BulkDataTransferServer::HandleBDXConnectionClosed(ExchangeContext *ec, WeaveConnection *con, WEAVE_ERROR conErr)
{
    printf("0 BDX HandleBDXConnectionClosed entering (conErr = %d)\n", conErr);
    BDXTransfer *xfer = (BDXTransfer* ) ec->AppState;
    BulkDataTransferServer *bdxApp = xfer->BdxApp;
    bdxApp->ShutdownTransfer(xfer, false);
    printf("1 BDX HandleBDXConnectionClosed exiting\n");
}

void BulkDataTransferServer::HandleResponseTimeout(ExchangeContext *ec)
{
    printf("0 BDX HandleResponseTimeout entering\n");
    BDXTransfer *xfer = (BDXTransfer* ) ec->AppState;
    BulkDataTransferServer *bdxApp = xfer->BdxApp;
    bdxApp->ShutdownTransfer(xfer, true);
    printf("1 BDX HandleResponseTimeout exiting\n");
}

void BulkDataTransferServer::SendTransferError(ExchangeContext *ec, uint32_t aProfileId, uint16_t aStatusCode)
{
    TransferError transferError;
    transferError.init(aProfileId, aStatusCode);
    PacketBuffer* payloadTransferError = PacketBuffer::New();
    if (payloadTransferError == NULL)
    {
        printf("BDX SendTransferError (PacketBuffer alloc failed)\n");
        return;
    }

    transferError.pack(payloadTransferError);
    ec->SendMessage(kWeaveProfile_BDX, kMsgType_TransferError, payloadTransferError);
    payloadTransferError = NULL;
}

} // namespace Profiles
} // namespace Weave
} // namespace nl
