void CToxProto::OnFileSendData(Tox*, uint32_t friendNumber, uint32_t fileNumber, uint64_t position, size_t length, void *arg) { CToxProto *proto = (CToxProto*)arg; FileTransferParam *transfer = proto->transfers.Get(friendNumber, fileNumber); if (transfer == NULL) { proto->logger->Log(__FUNCTION__": failed to find transfer (%d) to (%d)", fileNumber, friendNumber); return; } if (length == 0) { // file sending is finished proto->logger->Log(__FUNCTION__": finised the transfer of file (%d) to (%d)", fileNumber, friendNumber); bool isFileFullyTransfered = transfer->pfts.currentFileProgress == transfer->pfts.currentFileSize; if (!isFileFullyTransfered) proto->logger->Log(__FUNCTION__": file (%d) is not completely transferred to (%d)", fileNumber, friendNumber); proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, isFileFullyTransfered ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)transfer, 0); proto->transfers.Remove(transfer); return; } uint64_t sentBytes = _ftelli64(transfer->hFile); if (sentBytes != position) _fseeki64(transfer->hFile, position, SEEK_SET); uint8_t *data = (uint8_t*)mir_alloc(length); if (fread(data, sizeof(uint8_t), length, transfer->hFile) != length) { proto->logger->Log(__FUNCTION__": failed to read from file (%d) to (%d)", fileNumber, friendNumber); proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); tox_file_control(proto->toxThread->tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, NULL); mir_free(data); return; } TOX_ERR_FILE_SEND_CHUNK error; if (!tox_file_send_chunk(proto->toxThread->tox, friendNumber, fileNumber, position, data, length, &error)) { if (error == TOX_ERR_FILE_SEND_CHUNK_FRIEND_NOT_CONNECTED) { mir_free(data); return; } proto->logger->Log(__FUNCTION__": failed to send file chunk (%d) to (%d) cause (%d)", fileNumber, friendNumber, error); proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); tox_file_control(proto->toxThread->tox, transfer->friendNumber, transfer->fileNumber, TOX_FILE_CONTROL_CANCEL, NULL); mir_free(data); return; } transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += length; proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts); mir_free(data); }
static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position, size_t length, void *user_data) { if (*((uint32_t *)user_data) != 974536) { return; } if (!sendf_ok) { ck_abort_msg("Didn't get resume control"); } if (sending_pos != position) { ck_abort_msg("Bad position %llu", position); } if (length == 0) { if (file_sending_done) { ck_abort_msg("File sending already done."); } file_sending_done = 1; return; } if (position + length > max_sending) { if (m_send_reached) { ck_abort_msg("Requested done file tranfer."); } length = max_sending - position; m_send_reached = 1; } TOX_ERR_FILE_SEND_CHUNK error; uint8_t f_data[length]; memset(f_data, sending_num, length); if (tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error)) { ++sending_num; sending_pos += length; } else { ck_abort_msg("Could not send chunk %i", error); } if (error != TOX_ERR_FILE_SEND_CHUNK_OK) { ck_abort_msg("Wrong error code"); } }