add file_map
This commit is contained in:
parent
4dc3d7ccc1
commit
1ca053bea6
|
@ -71,6 +71,10 @@ async_scanner::~async_scanner()
|
||||||
cfg_mgr_->clear();
|
cfg_mgr_->clear();
|
||||||
delete cfg_mgr_;
|
delete cfg_mgr_;
|
||||||
}
|
}
|
||||||
|
for(auto& v: send_files_)
|
||||||
|
v->release();
|
||||||
|
send_files_.clear();
|
||||||
|
|
||||||
utils::uninit();
|
utils::uninit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +118,9 @@ dyn_mem_ptr async_scanner::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, pac
|
||||||
case PACK_CMD_FILE_READ_REQ:
|
case PACK_CMD_FILE_READ_REQ:
|
||||||
reply = handle_file_send(pack, used, required);
|
reply = handle_file_send(pack, used, required);
|
||||||
break;
|
break;
|
||||||
|
case PACK_CMD_FILE_READ_REQ_ROGER:
|
||||||
|
reply = handle_file_send_roger(pack, used, required);
|
||||||
|
break;
|
||||||
case PACK_CMD_SCAN_START:
|
case PACK_CMD_SCAN_START:
|
||||||
reply = handle_scan_start(pack, used, required);
|
reply = handle_scan_start(pack, used, required);
|
||||||
break;
|
break;
|
||||||
|
@ -256,7 +263,7 @@ dyn_mem_ptr async_scanner::handle_file_receive(LPPACK_BASE pack, uint32_t* used,
|
||||||
int err = 0;
|
int err = 0;
|
||||||
file_saver *saver = new file_saver();
|
file_saver *saver = new file_saver();
|
||||||
|
|
||||||
err = saver->open(path.c_str(), pfi->size);
|
err = saver->open(path.c_str(), pfi->size, true, pfi->offset);
|
||||||
reply = dyn_mem::memory(base_head_size);
|
reply = dyn_mem::memory(base_head_size);
|
||||||
reply->set_len(base_head_size);
|
reply->set_len(base_head_size);
|
||||||
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err);
|
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err);
|
||||||
|
@ -293,7 +300,7 @@ dyn_mem_ptr async_scanner::handle_file_send(LPPACK_BASE pack, uint32_t* used, pa
|
||||||
int err = 0;
|
int err = 0;
|
||||||
file_reader *reader = new file_reader();
|
file_reader *reader = new file_reader();
|
||||||
|
|
||||||
err = reader->open(path.c_str());
|
err = reader->open(path.c_str(), true, pfi->offset);
|
||||||
reply = dyn_mem::memory(base_head_size + sizeof(TXFILE));
|
reply = dyn_mem::memory(base_head_size + sizeof(TXFILE));
|
||||||
reply->set_len(base_head_size + sizeof(TXFILE));
|
reply->set_len(base_head_size + sizeof(TXFILE));
|
||||||
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err);
|
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), pack->cmd + 1, pack->pack_id, err);
|
||||||
|
@ -309,12 +316,52 @@ dyn_mem_ptr async_scanner::handle_file_send(LPPACK_BASE pack, uint32_t* used, pa
|
||||||
((LPPACK_BASE)reply->ptr())->payload_len = sizeof(TXFILE);
|
((LPPACK_BASE)reply->ptr())->payload_len = sizeof(TXFILE);
|
||||||
((LPTXFILE)((LPPACK_BASE)reply->ptr())->payload)->size = reader->get_rest();
|
((LPTXFILE)((LPPACK_BASE)reply->ptr())->payload)->size = reader->get_rest();
|
||||||
reader->set_packet_param(pack->cmd, pack->pack_id);
|
reader->set_packet_param(pack->cmd, pack->pack_id);
|
||||||
|
{
|
||||||
|
// move to PACK_CMD_FILE_READ_REQ_ROGER
|
||||||
|
SIMPLE_LOCK(fsender_);
|
||||||
|
send_files_.push_back(reader);
|
||||||
|
reader = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*required = dynamic_cast<packet_data_base_ptr>(reader);
|
*required = dynamic_cast<packet_data_base_ptr>(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
dyn_mem_ptr async_scanner::handle_file_send_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required)
|
||||||
|
{
|
||||||
|
uint32_t base_head_size = sizeof(PACK_BASE);
|
||||||
|
dyn_mem_ptr reply = nullptr;
|
||||||
|
|
||||||
|
if(*used < base_head_size)
|
||||||
|
{
|
||||||
|
*used = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file_reader* reader = nullptr;
|
||||||
|
|
||||||
|
{
|
||||||
|
SIMPLE_LOCK(fsender_);
|
||||||
|
for(size_t i = 0; i < send_files_.size(); ++i)
|
||||||
|
{
|
||||||
|
if(send_files_[i]->get_packet_id() == pack->pack_id)
|
||||||
|
{
|
||||||
|
reader = send_files_[i];
|
||||||
|
send_files_.erase(send_files_.begin() + i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*used = base_head_size;
|
||||||
|
*required = dynamic_cast<packet_data_base_ptr>(reader);
|
||||||
|
|
||||||
|
// if reader was nullptr, notify failed by INT or control ?
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "File Send beginning (%p) ...\n", reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required)
|
dyn_mem_ptr async_scanner::handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required)
|
||||||
{
|
{
|
||||||
if(!used)
|
if(!used)
|
||||||
|
|
|
@ -28,6 +28,9 @@ class async_scanner : public refer
|
||||||
volatile bool reply_start_;
|
volatile bool reply_start_;
|
||||||
int last_err_ = 0;
|
int last_err_ = 0;
|
||||||
|
|
||||||
|
MUTEX fsender_;
|
||||||
|
std::vector<file_reader*> send_files_;
|
||||||
|
|
||||||
dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
void init(void);
|
void init(void);
|
||||||
|
|
||||||
|
@ -37,6 +40,7 @@ class async_scanner : public refer
|
||||||
dyn_mem_ptr handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
dyn_mem_ptr handle_set_opt(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
dyn_mem_ptr handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
dyn_mem_ptr handle_file_receive(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
dyn_mem_ptr handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
dyn_mem_ptr handle_file_send(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
|
dyn_mem_ptr handle_file_send_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
dyn_mem_ptr handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
dyn_mem_ptr handle_scan_start(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
dyn_mem_ptr handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
dyn_mem_ptr handle_scan_stop(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
dyn_mem_ptr handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
dyn_mem_ptr handle_process_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required);
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if defined(WIN32) || defined(_WIN64)
|
#if OS_WIN
|
||||||
#else
|
#else
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -20,7 +21,7 @@ packet_data_base::~packet_data_base()
|
||||||
int packet_data_base::notify_progress(uint64_t total, uint64_t cur_size, uint32_t err)
|
int packet_data_base::notify_progress(uint64_t total, uint64_t cur_size, uint32_t err)
|
||||||
{
|
{
|
||||||
if (progress_notify_)
|
if (progress_notify_)
|
||||||
progress_notify_(total, cur_size, err, user_data_);
|
return progress_notify_(total, cur_size, err, user_data_);
|
||||||
else
|
else
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
@ -148,11 +149,16 @@ file_saver::file_saver(void) : size_(0), wrote_(0), path_(""), check_(""), dst_(
|
||||||
{}
|
{}
|
||||||
file_saver::~file_saver()
|
file_saver::~file_saver()
|
||||||
{
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "Write file(%s) over(%ld/%ld).\n", path_.c_str(), wrote_, size_);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void file_saver::close(void)
|
void file_saver::close(void)
|
||||||
{
|
{
|
||||||
|
if (map_)
|
||||||
|
map_->release();
|
||||||
|
map_ = nullptr;
|
||||||
|
|
||||||
if(dst_)
|
if(dst_)
|
||||||
fclose(dst_);
|
fclose(dst_);
|
||||||
dst_ = nullptr;
|
dst_ = nullptr;
|
||||||
|
@ -161,17 +167,48 @@ void file_saver::close(void)
|
||||||
path_ = check_ = "";
|
path_ = check_ = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
int file_saver::open(const char* path, uint64_t size, const char* check)
|
int file_saver::set_verify_data(const char* data, size_t len)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
check_ = std::string(data, len);
|
||||||
|
else
|
||||||
|
check_ = "";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int file_saver::open(const char* path, uint64_t size, bool in_mem, size_t off)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
close();
|
close();
|
||||||
dst_ = fopen(path, "wb");
|
wrote_ = off;
|
||||||
|
path_ = path;
|
||||||
|
size_ = size;
|
||||||
|
|
||||||
|
if (in_mem)
|
||||||
|
{
|
||||||
|
map_ = new file_map();
|
||||||
|
err = map_->open(path, size, false);
|
||||||
|
if (err || !map_->map())
|
||||||
|
{
|
||||||
|
map_->release();
|
||||||
|
map_ = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = utils::make_file_size(path, wrote_);
|
||||||
|
dst_ = fopen(path, "ab+");
|
||||||
if (dst_)
|
if (dst_)
|
||||||
{
|
{
|
||||||
unsigned long long space = 0;
|
unsigned long long space = 0;
|
||||||
|
std::string dir(path);
|
||||||
|
size_t pos = dir.rfind(PATH_SEPARATOR[0]);
|
||||||
|
|
||||||
err = utils::get_disk_space(path, nullptr, &space, nullptr);
|
if (pos != std::string::npos)
|
||||||
|
dir.erase(pos);
|
||||||
|
err = utils::get_disk_space(dir.c_str(), nullptr, &space, nullptr);
|
||||||
if (err || space < size * 1.5)
|
if (err || space < size * 1.5)
|
||||||
{
|
{
|
||||||
fclose(dst_);
|
fclose(dst_);
|
||||||
|
@ -180,12 +217,6 @@ int file_saver::open(const char* path, uint64_t size, const char* check)
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
err = ENOSPC;
|
err = ENOSPC;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
path_ = path;
|
|
||||||
size_ = size;
|
|
||||||
check_ = check ? check : "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -198,7 +229,21 @@ int file_saver::open(const char* path, uint64_t size, const char* check)
|
||||||
int file_saver::put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/)
|
int file_saver::put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/)
|
||||||
{
|
{
|
||||||
if (!dst_)
|
if (!dst_)
|
||||||
|
{
|
||||||
|
if (map_)
|
||||||
|
{
|
||||||
|
// fix me: we consider whole file is all mapped in memory
|
||||||
|
int w = *size > size_ - wrote_ ? size_ - wrote_ : *size;
|
||||||
|
memcpy(map_->buffer() + wrote_, data, w);
|
||||||
|
*size = w;
|
||||||
|
wrote_ += w;
|
||||||
|
notify_progress(size_, wrote_, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
int w = *size > size_ - wrote_ ? size_ - wrote_ : *size,
|
int w = *size > size_ - wrote_ ? size_ - wrote_ : *size,
|
||||||
real_w = fwrite(data, 1, w, dst_), // should handle error here !
|
real_w = fwrite(data, 1, w, dst_), // should handle error here !
|
||||||
|
@ -229,9 +274,11 @@ uint32_t file_saver::get_required(void)
|
||||||
}
|
}
|
||||||
void file_saver::cancel(void)
|
void file_saver::cancel(void)
|
||||||
{
|
{
|
||||||
|
std::string discard(path_);
|
||||||
|
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "Discard receiving file (%u/%u): '%s'.\n", wrote_, size_, path_.c_str());
|
utils::to_log(LOG_LEVEL_DEBUG, "Discard receiving file (%u/%u): '%s'.\n", wrote_, size_, path_.c_str());
|
||||||
close();
|
close();
|
||||||
remove(path_.c_str());
|
remove(discard.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -401,12 +448,41 @@ file_reader::~file_reader()
|
||||||
{
|
{
|
||||||
if(src_)
|
if(src_)
|
||||||
fclose(src_);
|
fclose(src_);
|
||||||
|
if (map_)
|
||||||
|
map_->release();
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "Read file(%s) over(%ld/%ld).\n", path_.c_str(), consume_, len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int file_reader::open(const char* file)
|
int file_reader::open(const char* file, bool in_mem, size_t off)
|
||||||
{
|
{
|
||||||
if(src_)
|
if(src_)
|
||||||
fclose(src_);
|
fclose(src_);
|
||||||
|
src_ = nullptr;
|
||||||
|
consume_ = off;
|
||||||
|
|
||||||
|
if (in_mem)
|
||||||
|
{
|
||||||
|
map_ = new file_map();
|
||||||
|
if (map_->open(file, 0, true) || !map_->map())
|
||||||
|
{
|
||||||
|
map_->release();
|
||||||
|
map_ = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (map_->total_size() <= off)
|
||||||
|
{
|
||||||
|
map_->release();
|
||||||
|
map_ = nullptr;
|
||||||
|
|
||||||
|
return EOVERFLOW;
|
||||||
|
}
|
||||||
|
path_ = file;
|
||||||
|
len_ = map_->total_size();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
src_ = fopen(file, "rb");
|
src_ = fopen(file, "rb");
|
||||||
if(!src_)
|
if(!src_)
|
||||||
|
@ -414,9 +490,15 @@ int file_reader::open(const char* file)
|
||||||
|
|
||||||
FSEEK(src_, 0, SEEK_END);
|
FSEEK(src_, 0, SEEK_END);
|
||||||
len_ = FTELL(src_);
|
len_ = FTELL(src_);
|
||||||
FSEEK(src_, 0, SEEK_SET);
|
FSEEK(src_, consume_, SEEK_SET);
|
||||||
path_ = file;
|
path_ = file;
|
||||||
consume_ = 0;
|
if (len_ <= consume_)
|
||||||
|
{
|
||||||
|
fclose(src_);
|
||||||
|
src_ = nullptr;
|
||||||
|
|
||||||
|
return EOVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -427,6 +509,11 @@ int file_reader::attach(FILE* f)
|
||||||
fclose(src_);
|
fclose(src_);
|
||||||
src_ = nullptr;
|
src_ = nullptr;
|
||||||
}
|
}
|
||||||
|
if (map_)
|
||||||
|
{
|
||||||
|
map_->release();
|
||||||
|
map_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t cur = FTELL(f);
|
uint64_t cur = FTELL(f);
|
||||||
|
|
||||||
|
@ -455,7 +542,7 @@ FILE* file_reader::detach(void)
|
||||||
|
|
||||||
bool file_reader::is_memory_block(void)
|
bool file_reader::is_memory_block(void)
|
||||||
{
|
{
|
||||||
return false;
|
return map_ != nullptr;
|
||||||
}
|
}
|
||||||
uint32_t file_reader::get_rest(void)
|
uint32_t file_reader::get_rest(void)
|
||||||
{
|
{
|
||||||
|
@ -465,14 +552,27 @@ uint32_t file_reader::get_rest(void)
|
||||||
// following API valid when is_memory_block() return true
|
// following API valid when is_memory_block() return true
|
||||||
uint8_t* file_reader::ptr(void)
|
uint8_t* file_reader::ptr(void)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return map_ ? map_->buffer() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// following API valid when is_memory_block() return false
|
// following API valid when is_memory_block() return false
|
||||||
int file_reader::fetch_data(void* buf, uint32_t* size)
|
int file_reader::fetch_data(void* buf, uint32_t* size)
|
||||||
{
|
{
|
||||||
if (!src_)
|
if (!src_)
|
||||||
|
{
|
||||||
|
if (map_)
|
||||||
|
{
|
||||||
|
if (*size + consume_ >= len_)
|
||||||
|
*size = len_ - consume_;
|
||||||
|
memcpy(buf, map_->buffer() + consume_, *size);
|
||||||
|
consume_ += *size;
|
||||||
|
notify_progress(len_, consume_, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return ENODATA;
|
return ENODATA;
|
||||||
|
}
|
||||||
|
|
||||||
size_t r = fread(buf, 1, *size, src_); // fix me if ERROR occurs !!!
|
size_t r = fread(buf, 1, *size, src_); // fix me if ERROR occurs !!!
|
||||||
|
|
||||||
|
@ -487,3 +587,200 @@ int file_reader::fetch_data(void* buf, uint32_t* size)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
file_map::file_map()
|
||||||
|
{
|
||||||
|
utils::get_page_size(&os_map_size_);
|
||||||
|
}
|
||||||
|
file_map::~file_map()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void file_map::unmap(void)
|
||||||
|
{
|
||||||
|
if (buf_)
|
||||||
|
#if OS_WIN
|
||||||
|
UnmapViewOfFile(buf_);
|
||||||
|
#else
|
||||||
|
munmap(buf_, map_size_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
buf_ = nullptr;
|
||||||
|
map_off_ = map_size_ = off_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int file_map::open(const char* file, uint64_t size, bool readonly)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
|
||||||
|
std::string oper(readonly ? "open" : "create");
|
||||||
|
|
||||||
|
#if OS_WIN
|
||||||
|
HANDLE h = INVALID_HANDLE_VALUE;
|
||||||
|
DWORD access = PAGE_READONLY;
|
||||||
|
if (readonly)
|
||||||
|
{
|
||||||
|
h = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
access = PAGE_READWRITE;
|
||||||
|
h = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
}
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: %s '%s' failed: %d\n", oper.c_str(), file, GetLastError());
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readonly)
|
||||||
|
{
|
||||||
|
DWORD* hi = (DWORD*)&size + 1,
|
||||||
|
* lo = (DWORD*)&size;
|
||||||
|
*lo = GetFileSize(h, hi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LONG lo = size & 0x0ffffffff,
|
||||||
|
hi = size >> 32;
|
||||||
|
DWORD ret = SetFilePointer(h, lo, &hi, FILE_BEGIN);
|
||||||
|
if (ret == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
|
||||||
|
{
|
||||||
|
CloseHandle(h);
|
||||||
|
remove(file);
|
||||||
|
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: no space(%ld) for '%s'.\n", size, file);
|
||||||
|
|
||||||
|
return ENOSPC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// write a byte to ensure map success
|
||||||
|
SetFilePointer(h, -1, NULL, FILE_CURRENT);
|
||||||
|
lo = 0;
|
||||||
|
WriteFile(h, &lo, 1, &ret, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map_ = CreateFileMappingA(h, NULL, access, 0, 0, NULL);
|
||||||
|
access = GetLastError();
|
||||||
|
CloseHandle(h);
|
||||||
|
if (!map_)
|
||||||
|
{
|
||||||
|
remove(file);
|
||||||
|
map_ = INVALID_HANDLE_VALUE;
|
||||||
|
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: create mapping object for '%s' failed: %d.\n", file, access);
|
||||||
|
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (readonly)
|
||||||
|
map_ = (HANDLE)::open(file, O_RDONLY, 0644);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int err = utils::make_file_size(file, size);
|
||||||
|
if(err)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_FATAL, "FileMapping: make file(%s) size(%ld) = %d\n", file, size, err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
map_ = (HANDLE)::open(file, O_RDWR, 0666);
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "FileMapping: open('%s', O_APPEND, 0666) = %p\n", file, map_);
|
||||||
|
}
|
||||||
|
if (map_ == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
int err = errno;
|
||||||
|
|
||||||
|
if(!readonly)
|
||||||
|
remove(file);
|
||||||
|
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: create mapping object for '%s' failed: %d.\n", file, err);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
path_file_ = file;
|
||||||
|
total_ = size;
|
||||||
|
read_only_ = readonly;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int file_map::close(void)
|
||||||
|
{
|
||||||
|
unmap();
|
||||||
|
|
||||||
|
if (map_ != INVALID_HANDLE_VALUE)
|
||||||
|
#if OS_WIN
|
||||||
|
CloseHandle(map_);
|
||||||
|
#else
|
||||||
|
::close((int)(long)map_);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
map_ = INVALID_HANDLE_VALUE;
|
||||||
|
total_ = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint64_t file_map::total_size(void)
|
||||||
|
{
|
||||||
|
return total_;
|
||||||
|
}
|
||||||
|
uint8_t* file_map::map(uint64_t off, uint32_t* size)
|
||||||
|
{
|
||||||
|
uint32_t len = 0;
|
||||||
|
|
||||||
|
unmap();
|
||||||
|
|
||||||
|
if (!size)
|
||||||
|
size = &len;
|
||||||
|
|
||||||
|
if (off < total_)
|
||||||
|
{
|
||||||
|
DWORD hi = 0,
|
||||||
|
lo = 0,
|
||||||
|
cnt = 0;
|
||||||
|
|
||||||
|
map_off_ = off / os_map_size_ * os_map_size_;
|
||||||
|
off_ = off - map_off_;
|
||||||
|
hi = map_off_ >> 32;
|
||||||
|
lo = map_off_;
|
||||||
|
cnt = total_ - map_off_;
|
||||||
|
if (cnt - off > *size && *size)
|
||||||
|
{
|
||||||
|
cnt = ALIGN_TO(*size + off, os_map_size_);
|
||||||
|
if(cnt > total_ - map_off_)
|
||||||
|
cnt = total_ - map_off_;
|
||||||
|
}
|
||||||
|
map_size_ = cnt;
|
||||||
|
#if OS_WIN
|
||||||
|
buf_ = (uint8_t*)MapViewOfFile(map_, read_only_ ? FILE_MAP_READ : FILE_MAP_READ | FILE_MAP_WRITE, hi, lo, map_size_);
|
||||||
|
#else
|
||||||
|
int priv = PROT_READ, prot = MAP_PRIVATE;
|
||||||
|
if (!read_only_)
|
||||||
|
{
|
||||||
|
priv |= PROT_WRITE;
|
||||||
|
prot = MAP_SHARED;
|
||||||
|
}
|
||||||
|
buf_ = (uint8_t*)mmap(nullptr, map_size_, priv, prot, (int)(long)map_, map_off_);
|
||||||
|
if(buf_ == INVALID_HANDLE_VALUE)
|
||||||
|
buf_ = nullptr;
|
||||||
|
#endif
|
||||||
|
if (!buf_)
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_WARNING, "FileMapping: request map(%p + %u), real map(%p + %u) failed: %d\n"
|
||||||
|
, off, *size, map_off_, map_size_, GetLastError());
|
||||||
|
*size = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*size = cnt - off;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf_ ? buf_ + off_ : nullptr;
|
||||||
|
}
|
||||||
|
uint8_t* file_map::buffer(void)
|
||||||
|
{
|
||||||
|
return buf_ ? buf_ + off_ : nullptr;
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,35 @@ public:
|
||||||
void set_progress_notify(PROGRESS_NOTIFYER notify = PROGRESS_NOTIFYER(), void* param = nullptr);
|
void set_progress_notify(PROGRESS_NOTIFYER notify = PROGRESS_NOTIFYER(), void* param = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class file_map : public refer
|
||||||
|
{
|
||||||
|
bool read_only_ = false; //
|
||||||
|
uint32_t os_map_size_ = 0; // desired mapping size of OS
|
||||||
|
uint64_t total_ = 0; // total size of the whole file
|
||||||
|
HANDLE map_ = INVALID_HANDLE_VALUE; // handle of the map-object
|
||||||
|
std::string path_file_; // local file
|
||||||
|
|
||||||
|
uint64_t map_off_ = 0; // offset in the file of current mapping buffer
|
||||||
|
uint32_t map_size_ = 0; // size of current mapping buffer
|
||||||
|
uint32_t off_ = 0; // offset to align to os_map_size_
|
||||||
|
uint8_t* buf_ = nullptr; // current mapping buffer
|
||||||
|
|
||||||
|
void unmap(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
file_map();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~file_map();
|
||||||
|
|
||||||
|
public:
|
||||||
|
int open(const char* file, uint64_t size, bool readonly);
|
||||||
|
int close(void);
|
||||||
|
uint64_t total_size(void);
|
||||||
|
uint8_t* map(uint64_t off = 0, uint32_t* size = 0); // size - in: desired size, 0 is from off to end; out: real size
|
||||||
|
uint8_t* buffer(void);
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
/* data_holder, used when data is also required for a certain packet
|
/* data_holder, used when data is also required for a certain packet
|
||||||
|
@ -112,6 +141,7 @@ class file_saver : public data_holder
|
||||||
std::string path_;
|
std::string path_;
|
||||||
std::string check_;
|
std::string check_;
|
||||||
FILE *dst_;
|
FILE *dst_;
|
||||||
|
file_map *map_ = nullptr;
|
||||||
uint32_t pack_cmd_;
|
uint32_t pack_cmd_;
|
||||||
uint32_t pack_id_;
|
uint32_t pack_id_;
|
||||||
|
|
||||||
|
@ -123,7 +153,8 @@ protected:
|
||||||
~file_saver();
|
~file_saver();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int open(const char* path, uint64_t size, const char* check = nullptr);
|
int set_verify_data(const char* data, size_t len);
|
||||||
|
int open(const char* path, uint64_t size, bool in_mem = false, size_t off = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override;
|
virtual int put_data(const void* data, uint32_t* size/*[in] - total bytes of data; [out] - used bytes*/) override;
|
||||||
|
@ -206,7 +237,8 @@ class file_reader : public data_source
|
||||||
{
|
{
|
||||||
size_t len_;
|
size_t len_;
|
||||||
size_t consume_;
|
size_t consume_;
|
||||||
FILE *src_;
|
FILE *src_ = nullptr;
|
||||||
|
file_map *map_ = nullptr;
|
||||||
std::string path_;
|
std::string path_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -216,7 +248,7 @@ protected:
|
||||||
~file_reader();
|
~file_reader();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int open(const char* file);
|
int open(const char* file, bool in_mem, size_t off = 0);
|
||||||
int attach(FILE* f);
|
int attach(FILE* f);
|
||||||
FILE* detach(void);
|
FILE* detach(void);
|
||||||
|
|
||||||
|
@ -231,6 +263,7 @@ public:
|
||||||
virtual int fetch_data(void* buf, uint32_t* size) override;
|
virtual int fetch_data(void* buf, uint32_t* size) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
CLS_PTR(packet_data_base);
|
CLS_PTR(packet_data_base);
|
||||||
CLS_PTR(data_holder);
|
CLS_PTR(data_holder);
|
||||||
CLS_PTR(mem_holder);
|
CLS_PTR(mem_holder);
|
||||||
|
@ -251,7 +284,7 @@ CLS_PTR(file_reader);
|
||||||
//
|
//
|
||||||
// when invalid packet, suggest use the entire data
|
// when invalid packet, suggest use the entire data
|
||||||
//
|
//
|
||||||
// packet_data_base_ptr* - return data_holder or data_source or nullptr <EFBFBD><EFBFBD>The number of bytes required for this packet, 0 is over for this packet<65><74>
|
// packet_data_base_ptr* - return data_holder or data_source or nullptr £¨The number of bytes required for this packet, 0 is over for this packet£©
|
||||||
//
|
//
|
||||||
// data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file'
|
// data_holder: the packet/command need more data than dyn_mem_ptr provides to complete the business. such as 'write a large file'
|
||||||
//
|
//
|
||||||
|
|
|
@ -50,13 +50,13 @@ enum ep0_req
|
||||||
USB_REQ_EP0_SET_ENCRYPT, // 设置加密方式, req = me, ind = 0, val = 0, len = sizeof(PACK_BASE)
|
USB_REQ_EP0_SET_ENCRYPT, // 设置加密方式, req = me, ind = 0, val = 0, len = sizeof(PACK_BASE)
|
||||||
USB_REQ_EP0_SET_BULK_BUFFER, // 设置bulk缓冲区大小系数, req = me, ind = coef, val = 0, len = 0
|
USB_REQ_EP0_SET_BULK_BUFFER, // 设置bulk缓冲区大小系数, req = me, ind = coef, val = 0, len = 0
|
||||||
};
|
};
|
||||||
enum bulk_status
|
enum woker_status
|
||||||
{
|
{
|
||||||
BULK_STATUS_NOT_START = 0, // has not initialized
|
WORKER_STATUS_NOT_START = 0, // has not start
|
||||||
BULK_STATUS_IDLE, // wait IO
|
WORKER_STATUS_IDLE, // idle
|
||||||
BULK_STATUS_IO, // in reading or writing
|
WORKER_STATUS_BUSY, // in working
|
||||||
BULK_STATUS_ERROR, // error occurs
|
WORKER_STATUS_ERROR, // error occurs
|
||||||
BULK_STATUS_RESET, // in reset(close and reopen) process
|
WORKER_STATUS_RESET, // in reset(close and reopen) process
|
||||||
};
|
};
|
||||||
|
|
||||||
enum packet_cmd
|
enum packet_cmd
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#if !OS_WIN // migrate codes from windows to linux ...
|
#if !OS_WIN // migrate codes from windows to linux ...
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
|
@ -97,6 +98,7 @@ typedef int BOOL;
|
||||||
#define USB_TIMEOUT_INFINITE 0
|
#define USB_TIMEOUT_INFINITE 0
|
||||||
#define FSEEK fseek
|
#define FSEEK fseek
|
||||||
#define FTELL ftell
|
#define FTELL ftell
|
||||||
|
#define INVALID_HANDLE_VALUE ((HANDLE)(-1))
|
||||||
|
|
||||||
|
|
||||||
extern DWORD GetLastError(void);
|
extern DWORD GetLastError(void);
|
||||||
|
@ -104,8 +106,8 @@ extern DWORD GetPrivateProfileIntA(const char* app, const char* key, DWORD def,
|
||||||
extern DWORD GetPrivateProfileStringA(const char* app, const char* key, const char* init, char* buf, size_t len, const char* file);
|
extern DWORD GetPrivateProfileStringA(const char* app, const char* key, const char* init, char* buf, size_t len, const char* file);
|
||||||
extern void Sleep(DWORD milliseconds);
|
extern void Sleep(DWORD milliseconds);
|
||||||
extern int GetModuleFileNameA(HMODULE module, char* buf, size_t len); // NOTE: parameter 'module' is consinder as a part of the module file name
|
extern int GetModuleFileNameA(HMODULE module, char* buf, size_t len); // NOTE: parameter 'module' is consinder as a part of the module file name
|
||||||
extern int GetCurrentProcessId(void);
|
extern uint64_t GetCurrentProcessId(void);
|
||||||
extern int GetCurrentThreadId(void);
|
extern uint64_t GetCurrentThreadId(void);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
|
@ -196,13 +196,13 @@ int GetModuleFileNameA(HMODULE module, char* buf, size_t len)
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
int GetCurrentThreadId(void)
|
uint64_t GetCurrentThreadId(void)
|
||||||
{
|
{
|
||||||
return pthread_self();
|
return (uint64_t)pthread_self();
|
||||||
}
|
}
|
||||||
int GetCurrentProcessId(void)
|
uint64_t GetCurrentProcessId(void)
|
||||||
{
|
{
|
||||||
return getpid();
|
return (uint64_t)getpid();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -236,7 +236,7 @@ class log_cls
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string sep("\n\n===================================================================================================================\n");
|
std::string sep("\n\n========================================================================================================================\n");
|
||||||
fwrite(sep.c_str(), sizeof(sep[0]), sep.length(), file_);
|
fwrite(sep.c_str(), sizeof(sep[0]), sep.length(), file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,10 +575,18 @@ namespace utils
|
||||||
}
|
}
|
||||||
rv = fread(buf, 1, sizeof(buf) - 1, src);
|
rv = fread(buf, 1, sizeof(buf) - 1, src);
|
||||||
}
|
}
|
||||||
|
if(rv == -1 && err)
|
||||||
|
{
|
||||||
|
*err = errno;
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "Failed to excute shell command '%s' in read pipe: %d - %s\n", cmd, errno, strerror(errno));
|
||||||
|
}
|
||||||
pclose(src);
|
pclose(src);
|
||||||
}
|
}
|
||||||
else if(err)
|
else if(err)
|
||||||
|
{
|
||||||
*err = errno;
|
*err = errno;
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "Failed to excute shell command '%s' in open pipe: %d - %s\n", cmd, errno, strerror(errno));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
|
@ -978,6 +986,36 @@ namespace utils
|
||||||
{
|
{
|
||||||
return rename(from, to);
|
return rename(from, to);
|
||||||
}
|
}
|
||||||
|
int make_file_size(const char* file, uint64_t size)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
get_command_result(("fallocate -l " + std::to_string(size) + " " + file).c_str(), -1, &err);
|
||||||
|
if(err == 0)
|
||||||
|
{
|
||||||
|
get_command_result(("truncate -s " + std::to_string(size) + " " + file).c_str(), -1, &err);
|
||||||
|
if(err == 0)
|
||||||
|
{
|
||||||
|
FILE* dst = fopen(file, "rb");
|
||||||
|
if(dst)
|
||||||
|
{
|
||||||
|
uint64_t rs = 0;
|
||||||
|
|
||||||
|
FSEEK(dst, 0, SEEK_END);
|
||||||
|
rs = FTELL(dst);
|
||||||
|
fclose(dst);
|
||||||
|
if(rs != size)
|
||||||
|
err = ENOSPC;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(err)
|
||||||
|
remove(file);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block)
|
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block)
|
||||||
{
|
{
|
||||||
|
@ -1049,7 +1087,7 @@ namespace utils
|
||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_log(log_type type, log_level level, const char* fn_appendix)
|
std::string init_log(log_type type, log_level level, const char* fn_appendix)
|
||||||
{
|
{
|
||||||
std::string file("");
|
std::string file("");
|
||||||
|
|
||||||
|
@ -1072,6 +1110,8 @@ namespace utils
|
||||||
|
|
||||||
log_cls::instance()->set_log_type(type, &file[0]);
|
log_cls::instance()->set_log_type(type, &file[0]);
|
||||||
log_cls::instance()->set_log_level(level);
|
log_cls::instance()->set_log_level(level);
|
||||||
|
|
||||||
|
return std::move(file);
|
||||||
}
|
}
|
||||||
void uninit(void)
|
void uninit(void)
|
||||||
{
|
{
|
||||||
|
@ -1872,22 +1912,22 @@ safe_thread::~safe_thread()
|
||||||
threads_.clear();
|
threads_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void safe_thread::thread_worker(std::function<void(void)> func, std::string name)
|
void safe_thread::thread_worker(std::function<void(void)> func, std::string name, void* addr)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "+++ safe_thread of '%s' is running ...\n", name.c_str());
|
utils::to_log(LOG_LEVEL_DEBUG, "+++ safe_thread of '%s(%p) - %p' is running ...\n", name.c_str(), addr, GetCurrentThreadId());
|
||||||
func();
|
func();
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "--- safe_thread of '%s' exited.\n", name.c_str());
|
utils::to_log(LOG_LEVEL_DEBUG, "--- safe_thread of '%s - %p' exited.\n", name.c_str(), GetCurrentThreadId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (std::exception e)
|
catch (std::exception e)
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_FATAL, "Exception in thread '%s': %s\n", name.c_str(), e.what());
|
utils::to_log(LOG_LEVEL_FATAL, "Exception in thread '%p - %s': %s\n", GetCurrentThreadId(), name.c_str(), e.what());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_FATAL, "Unknown exception in thread '%s'!\n", name.c_str());
|
utils::to_log(LOG_LEVEL_FATAL, "Unknown exception in thread '%p - %s'!\n", GetCurrentThreadId(), name.c_str());
|
||||||
}
|
}
|
||||||
excep_que_.save(name, true);
|
excep_que_.save(name, true);
|
||||||
}
|
}
|
||||||
|
@ -1908,12 +1948,12 @@ void safe_thread::set_exception_handler(std::function<void(const char*)> on_exce
|
||||||
{
|
{
|
||||||
excep_handler_ = on_exception;
|
excep_handler_ = on_exception;
|
||||||
}
|
}
|
||||||
int safe_thread::start(std::function<void(void)> f, const char* thread_name)
|
int safe_thread::start(std::function<void(void)> f, const char* thread_name, void* addr)
|
||||||
{
|
{
|
||||||
SAFETHRD st;
|
SAFETHRD st;
|
||||||
|
|
||||||
st.name = thread_name ? thread_name : "";
|
st.name = thread_name ? thread_name : "";
|
||||||
st.thread.reset(new std::thread(&safe_thread::thread_worker, this, f, thread_name));
|
st.thread.reset(new std::thread(&safe_thread::thread_worker, this, f, thread_name, addr));
|
||||||
|
|
||||||
{
|
{
|
||||||
SIMPLE_LOCK(lock_);
|
SIMPLE_LOCK(lock_);
|
||||||
|
|
|
@ -57,11 +57,13 @@ namespace utils
|
||||||
void set_ini_value(const char* seg, const char* key, const char* val, const char* cfg_file);
|
void set_ini_value(const char* seg, const char* key, const char* val, const char* cfg_file);
|
||||||
int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param);
|
int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param);
|
||||||
int move_file(const char* from, const char* to);
|
int move_file(const char* from, const char* to);
|
||||||
|
int make_file_size(const char* file, uint64_t size); // truncate or extend file size to 'size', create if not exist
|
||||||
|
|
||||||
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block);
|
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block);
|
||||||
unsigned int get_page_size(unsigned int* map_unit = nullptr);
|
unsigned int get_page_size(unsigned int* map_unit = nullptr);
|
||||||
|
|
||||||
void init_log(log_type type, log_level level = LOG_LEVEL_ALL, const char* fn_appendix = nullptr/*appendix to default log-file-name*/);
|
// return logging file path if 'type' was LOG_TYPE_FILE
|
||||||
|
std::string init_log(log_type type, log_level level = LOG_LEVEL_ALL, const char* fn_appendix = nullptr/*appendix to default log-file-name*/);
|
||||||
void uninit(void);
|
void uninit(void);
|
||||||
void log_info(const char* info, int level = LOG_LEVEL_ALL);
|
void log_info(const char* info, int level = LOG_LEVEL_ALL);
|
||||||
void log_mem_info(const char* desc, const void* data, size_t bytes, int level = LOG_LEVEL_ALL); // log as 0x12345678 00 01 02 ...
|
void log_mem_info(const char* desc, const void* data, size_t bytes, int level = LOG_LEVEL_ALL); // log as 0x12345678 00 01 02 ...
|
||||||
|
@ -354,7 +356,7 @@ class safe_thread
|
||||||
safe_fifo<std::string> excep_que_;
|
safe_fifo<std::string> excep_que_;
|
||||||
std::function<void(const char*)> excep_handler_ = std::function<void(const char*)>();
|
std::function<void(const char*)> excep_handler_ = std::function<void(const char*)>();
|
||||||
|
|
||||||
void thread_worker(std::function<void(void)> func, std::string name);
|
void thread_worker(std::function<void(void)> func, std::string name, void* addr);
|
||||||
void thread_notify_exception(void);
|
void thread_notify_exception(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -363,6 +365,6 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_exception_handler(std::function<void(const char*)> on_exception = std::function<void(const char*)>());
|
void set_exception_handler(std::function<void(const char*)> on_exception = std::function<void(const char*)>());
|
||||||
int start(std::function<void(void)> f, const char* thread_name);
|
int start(std::function<void(void)> f, const char* thread_name, void* addr = nullptr);
|
||||||
int stop(const char* thread_name);
|
int stop(const char* thread_name);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1158,13 +1158,42 @@ void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const c
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int index = -1;
|
int index = -1, pos = -1;
|
||||||
|
|
||||||
if (group)
|
if (group)
|
||||||
index = insert_group(group, group);
|
index = insert_group(group, group);
|
||||||
index = next_group(index + 1);
|
|
||||||
|
|
||||||
|
// insert poisition according to 'ui-pos'
|
||||||
|
if (!opt->get_value("ui-pos", pos) || pos == -1)
|
||||||
|
{
|
||||||
|
index = next_group(index + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (index++; index < origin_->children(); ++index)
|
||||||
|
{
|
||||||
|
gb_json* sib = origin_->child(index);
|
||||||
|
std::string t("");
|
||||||
|
int sit = -1;
|
||||||
|
|
||||||
|
if (!sib->get_value("type", t) || t == JSON_SANE_TYPE_GROUP)
|
||||||
|
{
|
||||||
|
sib->release();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!sib->get_value("ui-pos", sit) || sit == -1)
|
||||||
|
{
|
||||||
|
sib->release();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sib->release();
|
||||||
|
|
||||||
|
if (pos < sit)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
origin_->insert(index, opt->key().c_str(), opt);
|
origin_->insert(index, opt->key().c_str(), opt);
|
||||||
|
|
||||||
src_[opt->key()] = from;
|
src_[opt->key()] = from;
|
||||||
from->add_ref();
|
from->add_ref();
|
||||||
}
|
}
|
||||||
|
@ -1310,7 +1339,24 @@ gb_json* device_option::copy_opt(gb_json* from)
|
||||||
|
|
||||||
// 2: enabled ...
|
// 2: enabled ...
|
||||||
if (slaver_.count(to->key()))
|
if (slaver_.count(to->key()))
|
||||||
to->set_value("enabled", slaver_[to->key()]->value(&device_option::calc_simple_logic_expression, this));
|
{
|
||||||
|
bool enable = slaver_[to->key()]->value(&device_option::calc_simple_logic_expression, this);
|
||||||
|
to->set_value("enabled", enable);
|
||||||
|
if (src_.count(to->key()))
|
||||||
|
{
|
||||||
|
src_[to->key()]->enable(to->key().c_str(), enable);
|
||||||
|
|
||||||
|
sane_opt_provider* next = src_[to->key()]->get_following(to->key().c_str());
|
||||||
|
while (next)
|
||||||
|
{
|
||||||
|
next->enable(to->key().c_str(), enable);
|
||||||
|
|
||||||
|
sane_opt_provider* next1 = next->get_following(to->key().c_str());
|
||||||
|
next->release();
|
||||||
|
next = next1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 3: default value ...
|
// 3: default value ...
|
||||||
if (init_value_.count(to->key()))
|
if (init_value_.count(to->key()))
|
||||||
|
|
|
@ -688,6 +688,25 @@ int usb_device::close_device(void)
|
||||||
}
|
}
|
||||||
int usb_device::pull_up(std::string* msg)
|
int usb_device::pull_up(std::string* msg)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
int dst = open(udc_.c_str(), O_RDWR);
|
||||||
|
if(dst == -1)
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "Try write '%s' to '%s' failed(open): %s\n", dwc3_.c_str(), udc_.c_str(), strerror(errno));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int l = write(dst, dwc3_.c_str(), dwc3_.length()),
|
||||||
|
err = errno;
|
||||||
|
close(dst);
|
||||||
|
if(l == dwc3_.length())
|
||||||
|
{
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "pull up device by write '%s' to '%s' directly success.\n", dwc3_.c_str(), udc_.c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "Try write '%s' to '%s' failed(write): %s\n", dwc3_.c_str(), udc_.c_str(), strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string cmd("echo " + pwd_ + " | sudo -S sh -c \"echo " + dwc3_ + " > " + udc_ + "\"");
|
std::string cmd("echo " + pwd_ + " | sudo -S sh -c \"echo " + dwc3_ + " > " + udc_ + "\"");
|
||||||
int err = 0;
|
int err = 0;
|
||||||
std::string info(utils::get_command_result(cmd.c_str(), -1, &err));
|
std::string info(utils::get_command_result(cmd.c_str(), -1, &err));
|
||||||
|
|
113
usb/usb_io.cpp
113
usb/usb_io.cpp
|
@ -21,7 +21,8 @@ async_usb_gadget::async_usb_gadget(std::function<FUNCTION_PROTO_COMMAND_HANDLE>
|
||||||
, cmd_que_("in-queue"), sent_que_("out-queue")
|
, cmd_que_("in-queue"), sent_que_("out-queue")
|
||||||
, wait_in_("wait_usb_enable_in"), wait_out_("wait_usb_enable_out")
|
, wait_in_("wait_usb_enable_in"), wait_out_("wait_usb_enable_out")
|
||||||
{
|
{
|
||||||
memset((void*)&status_, 0, sizeof(status_));
|
cmd_que_.enable_wait_log(false);
|
||||||
|
sent_que_.enable_wait_log(false);
|
||||||
|
|
||||||
dev_ = new usb_device("fe900000.dwc3", "/opt/cfg/usb_gadget/g1/UDC", "linaro");
|
dev_ = new usb_device("fe900000.dwc3", "/opt/cfg/usb_gadget/g1/UDC", "linaro");
|
||||||
dev_->add_endpoint(USB_EP_BULK_IN, true, true);
|
dev_->add_endpoint(USB_EP_BULK_IN, true, true);
|
||||||
|
@ -87,10 +88,10 @@ async_usb_gadget::async_usb_gadget(std::function<FUNCTION_PROTO_COMMAND_HANDLE>
|
||||||
|
|
||||||
threads_.set_exception_handler(excep);
|
threads_.set_exception_handler(excep);
|
||||||
unit_in_ = unit_out_ = dev_->get_max_packet();
|
unit_in_ = unit_out_ = dev_->get_max_packet();
|
||||||
threads_.start(task, "thread_pump_task");
|
threads_.start(task, "thread_pump_task", (void*)&async_usb_gadget::thread_pump_task);
|
||||||
threads_.start(bulkw, "thread_read_bulk");
|
threads_.start(bulkw, "thread_write_bulk", (void*)&async_usb_gadget::thread_write_bulk);
|
||||||
threads_.start(bulkr, "thread_write_bulk");
|
threads_.start(bulkr, "thread_read_bulk", (void*)&async_usb_gadget::thread_read_bulk);
|
||||||
threads_.start(ep0, "thread_read_ep0");
|
threads_.start(ep0, "thread_read_ep0", (void*)&async_usb_gadget::thread_read_ep0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async_usb_gadget::~async_usb_gadget()
|
async_usb_gadget::~async_usb_gadget()
|
||||||
|
@ -149,19 +150,19 @@ dyn_mem_ptr async_usb_gadget::handle_ctrl_message(dyn_mem_ptr data)
|
||||||
switch (pev->type)
|
switch (pev->type)
|
||||||
{
|
{
|
||||||
case FUNCTIONFS_ENABLE:
|
case FUNCTIONFS_ENABLE:
|
||||||
utils::to_log(LOG_LEVEL_ALL, "EP0 FFS ENABLE\n");
|
|
||||||
online_ = true;
|
|
||||||
session_id_++;
|
session_id_++;
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "////////////// EP0 FFS ENABLE, start session %u ...\n", session_id_);
|
||||||
|
online_ = true;
|
||||||
wait_in_.trigger();
|
wait_in_.trigger();
|
||||||
wait_out_.trigger();
|
wait_out_.trigger();
|
||||||
if(dev_connect_)
|
if(dev_connect_)
|
||||||
dev_connect_(true);
|
dev_connect_(online_);
|
||||||
break;
|
break;
|
||||||
case FUNCTIONFS_DISABLE:
|
case FUNCTIONFS_DISABLE:
|
||||||
utils::to_log(LOG_LEVEL_ALL, "EP0 FFS DISABLE\n");
|
|
||||||
online_ = false;
|
online_ = false;
|
||||||
if(dev_connect_)
|
if(dev_connect_)
|
||||||
dev_connect_(false);
|
dev_connect_(online_);
|
||||||
|
utils::to_log(LOG_LEVEL_DEBUG, "////////////// EP0 FFS DISABLE, end session %u ...\n\n", session_id_);
|
||||||
break;
|
break;
|
||||||
case FUNCTIONFS_SETUP:
|
case FUNCTIONFS_SETUP:
|
||||||
reply = handle_ctrl_setup(data);
|
reply = handle_ctrl_setup(data);
|
||||||
|
@ -219,8 +220,17 @@ dyn_mem_ptr async_usb_gadget::handle_ctrl_setup(dyn_mem_ptr data)
|
||||||
break;
|
break;
|
||||||
case USB_REQ_EP0_GET_STATUS:
|
case USB_REQ_EP0_GET_STATUS:
|
||||||
reply = dyn_mem::memory(sizeof(struct _ep0_reply));
|
reply = dyn_mem::memory(sizeof(struct _ep0_reply));
|
||||||
|
reply->set_len(sizeof(struct _ep0_reply));
|
||||||
{
|
{
|
||||||
reply->put((void*)&status_, sizeof(status_));
|
LPEP0REPLYSTATUS lps = (LPEP0REPLYSTATUS)reply->ptr();
|
||||||
|
lps->in_status = statu_in_;
|
||||||
|
lps->out_status = statu_out_;
|
||||||
|
lps->task_cmd = task_cmd_;
|
||||||
|
lps->task_pack_id = task_packet_id_;
|
||||||
|
lps->task_required_bytes = want_bytes_task_;
|
||||||
|
lps->packets_to_sent = sent_que_.size();
|
||||||
|
lps->bytes_to_sent = want_bytes_in_;
|
||||||
|
utils::log_mem_info("threads status:", lps, sizeof(*lps), LOG_LEVEL_DEBUG);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USB_REQ_EP0_RESET_BULK:
|
case USB_REQ_EP0_RESET_BULK:
|
||||||
|
@ -255,6 +265,8 @@ dyn_mem_ptr async_usb_gadget::handle_ctrl_setup(dyn_mem_ptr data)
|
||||||
utils::to_log(LOG_LEVEL_ALL, "EP0 event(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) has not handled by user business.\n"
|
utils::to_log(LOG_LEVEL_ALL, "EP0 event(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) has not handled by user business.\n"
|
||||||
, pev->u.setup.bRequestType, pev->u.setup.bRequest, pev->u.setup.wValue, pev->u.setup.wIndex, pev->u.setup.wLength);
|
, pev->u.setup.bRequestType, pev->u.setup.bRequest, pev->u.setup.wValue, pev->u.setup.wIndex, pev->u.setup.wLength);
|
||||||
}
|
}
|
||||||
|
if(reply)
|
||||||
|
reply->set_session_id(data->get_session_id());
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
@ -264,13 +276,16 @@ int async_usb_gadget::inner_write_bulk(int fd, data_source_ptr data, int* err)
|
||||||
size_t bulk_size = unit_in_ * get_buf_coefficient(),
|
size_t bulk_size = unit_in_ * get_buf_coefficient(),
|
||||||
total = data->get_rest(), off = 0, size = total > bulk_size ? bulk_size : total;
|
total = data->get_rest(), off = 0, size = total > bulk_size ? bulk_size : total;
|
||||||
int w = 0;
|
int w = 0;
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
statu_in_ = WORKER_STATUS_BUSY;
|
||||||
|
want_bytes_in_ = total;
|
||||||
if(data->is_memory_block())
|
if(data->is_memory_block())
|
||||||
{
|
{
|
||||||
while((w = write(fd, ptr + off, size)) > 0)
|
while((w = write(fd, ptr + off, size)) > 0)
|
||||||
{
|
{
|
||||||
off += w;
|
off += w;
|
||||||
status_.bytes_to_sent -= w;
|
want_bytes_in_ -= w;
|
||||||
if(off >= total)
|
if(off >= total)
|
||||||
break;
|
break;
|
||||||
if(off + bulk_size < total)
|
if(off + bulk_size < total)
|
||||||
|
@ -279,8 +294,11 @@ int async_usb_gadget::inner_write_bulk(int fd, data_source_ptr data, int* err)
|
||||||
size = total - off;
|
size = total - off;
|
||||||
}
|
}
|
||||||
if(w <= 0 && err)
|
if(w <= 0 && err)
|
||||||
|
{
|
||||||
*err = errno;
|
*err = errno;
|
||||||
}
|
}
|
||||||
|
fail = w <= 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dyn_mem_ptr buf = dyn_mem::memory(bulk_size);
|
dyn_mem_ptr buf = dyn_mem::memory(bulk_size);
|
||||||
|
@ -296,7 +314,7 @@ int async_usb_gadget::inner_write_bulk(int fd, data_source_ptr data, int* err)
|
||||||
w = write(fd, ptr + off, len);
|
w = write(fd, ptr + off, len);
|
||||||
while(w > 0 && w + off < len)
|
while(w > 0 && w + off < len)
|
||||||
{
|
{
|
||||||
status_.bytes_to_sent -= w;
|
want_bytes_in_ -= w;
|
||||||
total += w;
|
total += w;
|
||||||
off += w;
|
off += w;
|
||||||
w = write(fd, ptr + off, len - off);
|
w = write(fd, ptr + off, len - off);
|
||||||
|
@ -304,14 +322,14 @@ int async_usb_gadget::inner_write_bulk(int fd, data_source_ptr data, int* err)
|
||||||
|
|
||||||
if(w <= 0)
|
if(w <= 0)
|
||||||
{
|
{
|
||||||
|
fail = true;
|
||||||
if(err)
|
if(err)
|
||||||
*err = errno;
|
*err = errno;
|
||||||
utils::to_log(LOG_LEVEL_ALL, "inner_write_bulk error(%d/%d): %d (%s)\n", off, len, errno, strerror(errno));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status_.bytes_to_sent -= w;
|
want_bytes_in_ -= w;
|
||||||
total += w;
|
total += w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +340,8 @@ int async_usb_gadget::inner_write_bulk(int fd, data_source_ptr data, int* err)
|
||||||
buf->release();
|
buf->release();
|
||||||
off = total;
|
off = total;
|
||||||
}
|
}
|
||||||
|
statu_in_ = fail ? WORKER_STATUS_ERROR : WORKER_STATUS_IDLE;
|
||||||
|
want_bytes_in_ = 0;
|
||||||
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +378,6 @@ void async_usb_gadget::thread_read_ep0(void)
|
||||||
std::string msg("");
|
std::string msg("");
|
||||||
struct usb_functionfs_event* pe = (struct usb_functionfs_event*)ptr;
|
struct usb_functionfs_event* pe = (struct usb_functionfs_event*)ptr;
|
||||||
|
|
||||||
utils::to_log(LOG_LEVEL_ALL, "EP0 monitoring thread(%p of id %lx) started ...\n", &async_usb_gadget::thread_read_ep0, getpid());
|
|
||||||
ret = dev_->pull_up(&msg);
|
ret = dev_->pull_up(&msg);
|
||||||
while(run_)
|
while(run_)
|
||||||
{
|
{
|
||||||
|
@ -424,17 +443,17 @@ void async_usb_gadget::thread_read_bulk(int fd)
|
||||||
dyn_mem_ptr buf(dyn_mem::memory(bulk_size));
|
dyn_mem_ptr buf(dyn_mem::memory(bulk_size));
|
||||||
int l = 0;
|
int l = 0;
|
||||||
|
|
||||||
status_.out_status = BULK_STATUS_IO;
|
statu_out_ = WORKER_STATUS_BUSY;
|
||||||
buf->set_session_id(session_id_);
|
buf->set_session_id(session_id_);
|
||||||
l = read(fd, buf->ptr(), bulk_size);
|
l = read(fd, buf->ptr(), bulk_size);
|
||||||
|
statu_out_ = WORKER_STATUS_IDLE;
|
||||||
if(l <= 0)
|
if(l <= 0)
|
||||||
{
|
{
|
||||||
buf->release();
|
buf->release();
|
||||||
if(errno)
|
if(errno)
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_ALL, "read bulk(%d) failed: %d(%s)\n", l, errno, strerror(errno));
|
utils::to_log(LOG_LEVEL_ALL, "read bulk(%d) failed: %d(%s)\n", l, errno, strerror(errno));
|
||||||
status_.out_status = BULK_STATUS_ERROR;
|
statu_out_ = WORKER_STATUS_ERROR;
|
||||||
status_.out_err = errno;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -446,22 +465,19 @@ void async_usb_gadget::thread_read_bulk(int fd)
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_ALL, "thread_read_bulk do reset-bulk ...\n");
|
utils::to_log(LOG_LEVEL_ALL, "thread_read_bulk do reset-bulk ...\n");
|
||||||
buf->release();
|
buf->release();
|
||||||
if(!run_)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status_.out_status = BULK_STATUS_IDLE;
|
|
||||||
buf->set_len(l);
|
buf->set_len(l);
|
||||||
cmd_que_.save(buf, true);
|
cmd_que_.save(buf, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(status_.out_status == BULK_STATUS_IDLE)
|
statu_out_ = WORKER_STATUS_NOT_START;
|
||||||
status_.out_status = BULK_STATUS_NOT_START;
|
|
||||||
}
|
}
|
||||||
void async_usb_gadget::thread_write_bulk(int fd)
|
void async_usb_gadget::thread_write_bulk(int fd)
|
||||||
{
|
{
|
||||||
status_.in_status = BULK_STATUS_IDLE;
|
statu_in_ = WORKER_STATUS_IDLE;
|
||||||
while(run_)
|
while(run_)
|
||||||
{
|
{
|
||||||
data_source_ptr data;
|
data_source_ptr data;
|
||||||
|
@ -469,24 +485,17 @@ void async_usb_gadget::thread_write_bulk(int fd)
|
||||||
|
|
||||||
if(sent_que_.take(data, true))
|
if(sent_que_.take(data, true))
|
||||||
{
|
{
|
||||||
status_.packets_to_sent = sent_que_.size();
|
want_bytes_in_ = data->get_rest();
|
||||||
status_.bytes_to_sent = data->get_rest();
|
|
||||||
status_.in_status = BULK_STATUS_IO;
|
|
||||||
inner_write_bulk(fd, data, &err);
|
inner_write_bulk(fd, data, &err);
|
||||||
status_.in_status = BULK_STATUS_IDLE;
|
|
||||||
status_.bytes_to_sent = 0;
|
|
||||||
data->release();
|
data->release();
|
||||||
if(err)
|
if(err)
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_ALL, "write bulk failed: %d(%s)\n", errno, strerror(errno));
|
utils::to_log(LOG_LEVEL_ALL, "write bulk failed: %d(%s)\n", errno, strerror(errno));
|
||||||
status_.in_status = BULK_STATUS_ERROR;
|
|
||||||
status_.in_err = err;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(status_.in_status == BULK_STATUS_IDLE)
|
statu_in_ = WORKER_STATUS_NOT_START;
|
||||||
status_.in_status = BULK_STATUS_NOT_START;
|
|
||||||
}
|
}
|
||||||
void async_usb_gadget::thread_pump_task(void)
|
void async_usb_gadget::thread_pump_task(void)
|
||||||
{
|
{
|
||||||
|
@ -500,11 +509,12 @@ void async_usb_gadget::thread_pump_task(void)
|
||||||
while(run_)
|
while(run_)
|
||||||
{
|
{
|
||||||
data = nullptr;
|
data = nullptr;
|
||||||
|
statu_task_ = WORKER_STATUS_IDLE;
|
||||||
if(cmd_que_.take(data, true) && data)
|
if(cmd_que_.take(data, true) && data)
|
||||||
{
|
{
|
||||||
status_.task_cnt = cmd_que_.size();
|
statu_task_ = WORKER_STATUS_BUSY;
|
||||||
if(max_que < status_.task_cnt)
|
if(max_que < cmd_que_.size())
|
||||||
max_que = status_.task_cnt;
|
max_que = cmd_que_.size();
|
||||||
|
|
||||||
if(prev)
|
if(prev)
|
||||||
{
|
{
|
||||||
|
@ -549,8 +559,9 @@ void async_usb_gadget::thread_pump_task(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pack = (LPPACK_BASE)data->ptr();
|
pack = (LPPACK_BASE)data->ptr();
|
||||||
status_.task_cmd = pack->cmd;
|
task_cmd_ = pack->cmd;
|
||||||
status_.task_pack_id = pack->pack_id;
|
task_packet_id_ = pack->pack_id;
|
||||||
|
want_bytes_task_ = 0;
|
||||||
used = data->get_rest();
|
used = data->get_rest();
|
||||||
reply = handle_bulk_command(data, &used, &pack_data);
|
reply = handle_bulk_command(data, &used, &pack_data);
|
||||||
notify_reply_ok = used & (INT32_MAX + 1);
|
notify_reply_ok = used & (INT32_MAX + 1);
|
||||||
|
@ -564,9 +575,14 @@ void async_usb_gadget::thread_pump_task(void)
|
||||||
ds = dynamic_cast<data_source_ptr>(pack_data);
|
ds = dynamic_cast<data_source_ptr>(pack_data);
|
||||||
if(!ds)
|
if(!ds)
|
||||||
pack_data->release();
|
pack_data->release();
|
||||||
|
else
|
||||||
|
want_bytes_task_ = ds->get_rest();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
total_size = 0;
|
total_size = 0;
|
||||||
|
want_bytes_task_ = dh->get_required();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,10 +604,15 @@ void async_usb_gadget::thread_pump_task(void)
|
||||||
BASE_PACKET_REPLY(*pack, dh->get_packet_command() + 1, dh->get_packet_id(), err);
|
BASE_PACKET_REPLY(*pack, dh->get_packet_command() + 1, dh->get_packet_id(), err);
|
||||||
reply->set_len(sizeof(PACK_BASE));
|
reply->set_len(sizeof(PACK_BASE));
|
||||||
|
|
||||||
utils::to_log(LOG_LEVEL_ALL, "Finished receiving file with error(Max queue size is %u): %d, total size = 0x%x\n", max_que, err, total_size);
|
utils::to_log(LOG_LEVEL_ALL, "Finished receiving large data with error(Max queue size is %u): %d, total size = 0x%x\n", max_que, err, total_size);
|
||||||
|
|
||||||
dh->release();
|
dh->release();
|
||||||
dh = nullptr;
|
dh = nullptr;
|
||||||
|
want_bytes_task_ = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
want_bytes_task_ = dh->get_required();
|
||||||
}
|
}
|
||||||
used = len;
|
used = len;
|
||||||
|
|
||||||
|
@ -612,7 +633,7 @@ void async_usb_gadget::thread_pump_task(void)
|
||||||
reply->release();
|
reply->release();
|
||||||
reply = enc;
|
reply = enc;
|
||||||
}
|
}
|
||||||
|
reply->set_session_id(data->get_session_id());
|
||||||
write_bulk(dynamic_cast<data_source_ptr>(reply));
|
write_bulk(dynamic_cast<data_source_ptr>(reply));
|
||||||
if(notify_reply_ok)
|
if(notify_reply_ok)
|
||||||
handle_bulk_command(data, nullptr, nullptr);
|
handle_bulk_command(data, nullptr, nullptr);
|
||||||
|
@ -628,19 +649,21 @@ void async_usb_gadget::thread_pump_task(void)
|
||||||
ds = nullptr;
|
ds = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_.task_required_bytes = dh ? dh->get_required() : 0;
|
|
||||||
if(status_.task_required_bytes == 0)
|
|
||||||
status_.task_cmd = status_.task_pack_id = 0;
|
|
||||||
|
|
||||||
data->used(used);
|
data->used(used);
|
||||||
}while(used && data->get_rest());
|
}while(used && data->get_rest());
|
||||||
|
|
||||||
if(data->get_rest())
|
if(data->get_rest())
|
||||||
prev = data;
|
prev = data;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if(!dh)
|
||||||
|
{
|
||||||
|
task_cmd_ = task_packet_id_ = want_bytes_task_ = 0;
|
||||||
|
}
|
||||||
data->release();
|
data->release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(prev)
|
if(prev)
|
||||||
prev->release();
|
prev->release();
|
||||||
if (data)
|
if (data)
|
||||||
|
@ -674,7 +697,7 @@ int async_usb_gadget::write_bulk(data_source_ptr data)
|
||||||
{
|
{
|
||||||
if(data->get_session_id() != session_id_ || !online_)
|
if(data->get_session_id() != session_id_ || !online_)
|
||||||
{
|
{
|
||||||
utils::to_log(LOG_LEVEL_DEBUG, "Discard packet for the session ID(%u) is not equal current session(%u) or is offline.\n", data->get_session_id(), session_id_);
|
utils::to_log(LOG_LEVEL_DEBUG, "Discard reply packet for the session ID(%u) is not equal current session(%u) or is offline.\n", data->get_session_id(), session_id_);
|
||||||
data->release();
|
data->release();
|
||||||
|
|
||||||
return sent_que_.size();
|
return sent_que_.size();
|
||||||
|
|
11
usb/usb_io.h
11
usb/usb_io.h
|
@ -59,7 +59,16 @@ class async_usb_gadget : public refer
|
||||||
uint8_t enc_data_;
|
uint8_t enc_data_;
|
||||||
int last_err_ = 0;
|
int last_err_ = 0;
|
||||||
|
|
||||||
volatile EP0REPLYSTATUS status_;
|
uint8_t statu_in_ = WORKER_STATUS_NOT_START;
|
||||||
|
uint32_t want_bytes_in_ = 0;
|
||||||
|
|
||||||
|
uint8_t statu_out_ = WORKER_STATUS_NOT_START;
|
||||||
|
|
||||||
|
uint8_t statu_task_ = WORKER_STATUS_NOT_START;
|
||||||
|
uint32_t want_bytes_task_ = 0;
|
||||||
|
uint32_t task_cmd_ = 0;
|
||||||
|
uint32_t task_packet_id_ = 0;
|
||||||
|
|
||||||
safe_fifo<dyn_mem_ptr> cmd_que_;
|
safe_fifo<dyn_mem_ptr> cmd_que_;
|
||||||
safe_fifo<data_source_ptr> sent_que_;
|
safe_fifo<data_source_ptr> sent_que_;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue