void DataFlash_MAVLink::do_resends(uint32_t now)
{
    if (!_initialised || !_logging_started ||!_sending_to_client) {
        return;
    }

    uint8_t count_to_send = 5;
    if (_blockcount < count_to_send) {
        count_to_send = _blockcount;
    }
    uint32_t oldest = now - 100; // 100 milliseconds before resend.  Hmm.
    while (count_to_send-- > 0) {
        if (!semaphore->take_nonblocking()) {
            return;
        }
        for (struct dm_block *block=_blocks_sent.oldest; block != nullptr; block=block->next) {
            // only want to send blocks every now-and-then:
            if (block->last_sent < oldest) {
                if (! send_log_block(*block)) {
                    // failed to send the block; try again later....
                    semaphore->give();
                    return;
                }
                stats.resends++;
            }
        }
        semaphore->give();
    }
}
void DataFlash_MAVLink::handle_retry(uint32_t block_num)
{
    if (!_initialised) {
        return;
    }
    _last_response_time = hal.scheduler->millis();
    for(uint8_t block = 0; block < _total_blocks; block++){
        if(_block_num[block] == block_num) {
            send_log_block(block);
            return;
        }
    }
}
/* while we "successfully" send log blocks from a queue, move them to
 * the sent list. DO NOT call this for blocks already sent!
*/
bool DataFlash_MAVLink::send_log_blocks_from_queue(dm_block_queue_t &queue)
{
    uint8_t sent_count = 0;
    while (queue.oldest != NULL) {
        if (sent_count++ > _max_blocks_per_send_blocks) {
            return false;
        }
        if (! send_log_block(*queue.oldest)) {
            return false;
        }
        queue.sent_count++;
        struct DataFlash_MAVLink::dm_block *tmp = dequeue_seqno(queue,queue.oldest->seqno);
        if (tmp != NULL) { // should never be NULL
            enqueue_block(_blocks_sent, tmp);
        } else {
            internal_error();
        }
    }
    return true;
}
/* Write a block of data at current offset */
void DataFlash_MAVLink::WriteBlock(const void *pBuffer, uint16_t size)
{
    if (!_initialised || !_logging_started) {
        return;
    }

    //transfer nothing else when in the middle of doing critical blocks (Parameters and Formats) transaction
    if(is_critical_block) {
        _only_critical_blocks = true;
    }
    if(!is_critical_block && ((hal.scheduler->millis() - _last_response_time) > 2000 || _buffer_empty())) {
        for(uint8_t block = 0; block < NUM_BUFFER_BLOCKS; block++) {
            _is_critical_block[block] = false;
        }
        _only_critical_blocks = false;
    }
    if(!is_critical_block && _only_critical_blocks) {
        return;
    }

    uint16_t copied = 0;

    while (copied < size) {
        if(is_critical_block) {
            _is_critical_block[_cur_block_address] = true;
        }
        uint16_t remaining_to_copy = size - copied;
        uint16_t _curr_remaining = _block_max_size - _latest_block_len;
        uint16_t to_copy = (remaining_to_copy > _curr_remaining) ? _curr_remaining : remaining_to_copy;
        memcpy(&_buf[_cur_block_address][_latest_block_len], &((const uint8_t *)pBuffer)[copied], to_copy);
        copied += to_copy;
        _latest_block_len += to_copy;
        if (_latest_block_len == _block_max_size) {
            send_log_block(_cur_block_address);  //block full send it
            _cur_block_address = next_block_address();
        }
    }
}