You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
4.2 KiB
121 lines
4.2 KiB
// media_download.h — скачивание блоков медиа |
|
#ifndef MEDIA_DOWNLOAD_H |
|
#define MEDIA_DOWNLOAD_H |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#include <stdint.h> |
|
#include <stddef.h> |
|
#include <stdio.h> |
|
#include "../lib/ll_queue.h" |
|
|
|
struct UTUN_INSTANCE; |
|
struct media_index_result; |
|
|
|
struct UTUN_INSTANCE; |
|
struct media_index_result; |
|
|
|
/* максимальное число параллельных блоков на пира (один стрим на блок) */ |
|
#define MD_MAX_BLOCKS_PER_PEER 64 |
|
|
|
struct media_download_peer { |
|
uint64_t node_id; |
|
uint8_t connected; |
|
void* cm_handle; |
|
int num_blocks; |
|
struct { |
|
uint8_t block_id[16]; |
|
uint8_t started; |
|
uint8_t received; |
|
uint8_t validated; |
|
} blocks[MD_MAX_BLOCKS_PER_PEER]; |
|
}; |
|
|
|
/* внутреннее состояние загрузки (доступно для тестов) */ |
|
struct media_download { |
|
struct ll_entry ll; |
|
uint8_t media_id[16]; |
|
uint64_t group_id; |
|
char dest_path[1024]; |
|
char media_base[512]; |
|
int num_blocks; |
|
uint8_t* block_ids; |
|
uint8_t* block_sigs; |
|
uint8_t content_hash[32]; |
|
int64_t file_size; |
|
int64_t block_size; |
|
int blocks_received; |
|
int blocks_validated; |
|
int num_peers; |
|
struct media_download_peer peers[10]; |
|
uint8_t active; |
|
uint8_t assembled; |
|
int err; |
|
uint64_t super_nodes[10]; |
|
int super_count; |
|
int super_current; |
|
uint64_t author_node_id; /* src_node_id from chat message, for fallback when supernode has no info */ |
|
void* query_timer; |
|
void* timeout_timer; |
|
void (*done_cb)(void* arg, int err); |
|
void* done_arg; |
|
void (*progress_cb)(void* arg, int blocks_done, int num_blocks); |
|
void* progress_arg; |
|
struct UTUN_INSTANCE* inst; |
|
}; |
|
|
|
/* состояние одного стрима на стороне блок-холдера */ |
|
struct media_block_stream { |
|
uint8_t media_id[16]; |
|
uint8_t block_id[16]; |
|
uint32_t chunk; |
|
uint64_t offset; // текущее смещение в блоке |
|
uint32_t bytes_sent; // всего отправлено байт |
|
uint32_t total_size; // ожидаемый размер блока |
|
uint8_t done; // 1 = стрим завершён |
|
void* waiter; // handle etcp_router_on_send_ready |
|
FILE* file; // fd исходного файла |
|
uint64_t dst_node_id; |
|
uint64_t group_id; |
|
}; |
|
|
|
int media_download_start(struct UTUN_INSTANCE* inst, uint64_t group_id, |
|
const struct media_index_result* result, |
|
const char* dest_path, const char* media_base, |
|
uint64_t author_node_id, |
|
void (*done_cb)(void* arg, int err), void* done_arg, |
|
void (*progress_cb)(void* arg, int blocks_done, int num_blocks), void* progress_arg); |
|
|
|
int media_download_cancel(struct UTUN_INSTANCE* inst, |
|
const uint8_t* media_id, const uint8_t* block_id, uint32_t chunk); |
|
|
|
/* ── handlers for incoming data, called from md_etcp_recv dispatch ── */ |
|
|
|
struct ll_entry; |
|
struct UTUN_INSTANCE; |
|
|
|
void media_download_handle_query_resp(struct UTUN_INSTANCE* inst, |
|
const uint8_t* data, size_t len); |
|
void media_download_handle_chunk(struct UTUN_INSTANCE* inst, |
|
const uint8_t* data, size_t len); |
|
void media_download_handle_done(struct UTUN_INSTANCE* inst, |
|
const uint8_t* data, size_t len); |
|
void media_download_handle_overloaded(struct UTUN_INSTANCE* inst, |
|
const uint8_t* data, size_t len); |
|
|
|
void media_download_handle_relay_full(struct UTUN_INSTANCE* inst, |
|
const uint8_t* media_id, const uint8_t* block_id, |
|
uint32_t chunk, const uint64_t* node_ids, int num_nodes); |
|
|
|
/* ── conn_mgr callback (non-static for test visibility) ── */ |
|
struct CONN_MGR_HANDLE; |
|
enum conn_mgr_event; |
|
void md_dl_conn_cb(struct CONN_MGR_HANDLE* h, uint64_t node_id, uint64_t group_id, |
|
enum conn_mgr_event event, void* arg); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
#endif
|
|
|