forked from Ivasoft/DSView
Load data in sections for each channel
This commit is contained in:
@@ -91,7 +91,6 @@ void LogicSnapshot::init_all()
|
||||
_block_num = 0;
|
||||
_byte_fraction = 0;
|
||||
_ch_fraction = 0;
|
||||
_src_ptr = NULL;
|
||||
_dest_ptr = NULL;
|
||||
_data = NULL;
|
||||
_memory_failed = false;
|
||||
@@ -140,9 +139,11 @@ void LogicSnapshot::capture_ended()
|
||||
// calc root of current block
|
||||
if (*((uint64_t *)iter[index0].lbp[index1]) != 0)
|
||||
iter[index0].value += 1ULL << index1;
|
||||
|
||||
if (*((uint64_t *)iter[index0].lbp[index1] + LeafBlockSpace / sizeof(uint64_t) - 1) != 0) {
|
||||
iter[index0].tog += 1ULL << index1;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// trim leaf to free space
|
||||
free(iter[index0].lbp[index1]);
|
||||
iter[index0].lbp[index1] = NULL;
|
||||
@@ -206,7 +207,7 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total
|
||||
}
|
||||
}
|
||||
|
||||
assert(_channel_num < LOGIC_TMP_BUF_MAX_SIZE);
|
||||
assert(_channel_num < CHANNEL_MAX_COUNT);
|
||||
|
||||
_sample_count = 0;
|
||||
|
||||
@@ -225,10 +226,7 @@ void LogicSnapshot::append_payload(const sr_datafeed_logic &logic)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
if (logic.format == LA_CROSS_DATA)
|
||||
append_cross_payload(logic);
|
||||
else if (logic.format == LA_SPLIT_DATA)
|
||||
append_split_payload(logic);
|
||||
append_cross_payload(logic);
|
||||
|
||||
_have_data = true;
|
||||
}
|
||||
@@ -241,7 +239,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
if (_sample_count >= _total_sample_count)
|
||||
return;
|
||||
|
||||
_src_ptr = logic.data;
|
||||
void *data_src_ptr = logic.data;
|
||||
uint64_t len = logic.length;
|
||||
// samples not accurate, lead to a larger _sampole_count
|
||||
// _sample_count should be fixed in the last packet
|
||||
@@ -249,16 +247,16 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
uint64_t samples = ceil(logic.length * 8.0 / _channel_num);
|
||||
if (_sample_count + samples < _total_sample_count) {
|
||||
_sample_count += samples;
|
||||
} else {
|
||||
//len = ceil((_total_sample_count - _sample_count) * _channel_num / 8.0);
|
||||
}
|
||||
else {
|
||||
_sample_count = _total_sample_count;
|
||||
}
|
||||
|
||||
while (_sample_count > _block_num * LeafBlockSamples) {
|
||||
uint8_t index0 = _block_num / RootScale;
|
||||
uint8_t index1 = _block_num % RootScale;
|
||||
for(auto& iter : _ch_data) {
|
||||
|
||||
for(auto& iter : _ch_data) {
|
||||
if (iter[index0].lbp[index1] == NULL){
|
||||
iter[index0].lbp[index1] = malloc(LeafBlockSpace);
|
||||
|
||||
@@ -268,8 +266,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t *mipmap_ptr = (uint64_t *)iter[index0].lbp[index1] +
|
||||
(LeafBlockSamples / Scale);
|
||||
uint64_t *mipmap_ptr = (uint64_t *)iter[index0].lbp[index1] + (LeafBlockSamples / Scale);
|
||||
memset(mipmap_ptr, 0, LeafBlockSpace - (LeafBlockSamples / 8));
|
||||
}
|
||||
_block_num++;
|
||||
@@ -278,17 +275,21 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
// bit align
|
||||
while (((_ch_fraction != 0) || (_byte_fraction != 0)) && (len != 0)) {
|
||||
uint8_t *dp_tmp = (uint8_t *)_dest_ptr;
|
||||
uint8_t *sp_tmp = (uint8_t *)_src_ptr;
|
||||
uint8_t *sp_tmp = (uint8_t *)data_src_ptr;
|
||||
|
||||
if (_dest_ptr == NULL){
|
||||
assert(false);
|
||||
}
|
||||
|
||||
do {
|
||||
//*(uint8_t *)_dest_ptr++ = *(uint8_t *)_src_ptr++;
|
||||
*dp_tmp++ = *sp_tmp++;
|
||||
_byte_fraction = (_byte_fraction + 1) % ScaleSize;
|
||||
len--;
|
||||
} while ((_byte_fraction != 0) && (len != 0));
|
||||
}
|
||||
while ((_byte_fraction != 0) && (len != 0));
|
||||
|
||||
_dest_ptr = dp_tmp;
|
||||
_src_ptr = sp_tmp;
|
||||
data_src_ptr = sp_tmp;
|
||||
|
||||
if (_byte_fraction == 0) {
|
||||
const uint64_t index0 = _ring_sample_count / RootNodeSamples;
|
||||
@@ -307,24 +308,25 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
assert(_ch_fraction == 0);
|
||||
assert(_byte_fraction == 0);
|
||||
assert(_ring_sample_count % Scale == 0);
|
||||
|
||||
uint64_t pre_index0 = _ring_sample_count / RootNodeSamples;
|
||||
uint64_t pre_index1 = (_ring_sample_count >> LeafBlockPower) % RootScale;
|
||||
uint64_t pre_offset = (_ring_sample_count % LeafBlockSamples) / Scale;
|
||||
uint64_t *src_ptr = NULL;
|
||||
uint64_t *dest_ptr;
|
||||
int order = 0;
|
||||
const uint64_t align_size = len / ScaleSize / _channel_num;
|
||||
const uint64_t align_size = len / _channel_num / ScaleSize;
|
||||
_ring_sample_count += align_size * Scale;
|
||||
|
||||
|
||||
for(auto& iter : _ch_data) {
|
||||
for(auto& iter : _ch_data)
|
||||
{
|
||||
uint64_t index0 = pre_index0;
|
||||
uint64_t index1 = pre_index1;
|
||||
src_ptr = (uint64_t *)_src_ptr + order;
|
||||
src_ptr = (uint64_t *)data_src_ptr + order;
|
||||
_dest_ptr = iter[index0].lbp[index1];
|
||||
dest_ptr = (uint64_t *)_dest_ptr + pre_offset;
|
||||
|
||||
while (src_ptr < (uint64_t *)_src_ptr + (align_size * _channel_num)) {
|
||||
while (src_ptr < (uint64_t *)data_src_ptr + (align_size * _channel_num)) {
|
||||
const uint64_t tmp_u64 = *src_ptr;
|
||||
*dest_ptr++ = tmp_u64;
|
||||
src_ptr += _channel_num;
|
||||
@@ -355,8 +357,9 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
}
|
||||
order++;
|
||||
}
|
||||
|
||||
len -= align_size * _channel_num * ScaleSize;
|
||||
_src_ptr = src_ptr - _channel_num + 1;
|
||||
data_src_ptr = src_ptr - _channel_num + 1;
|
||||
}
|
||||
|
||||
// fraction data append
|
||||
@@ -367,7 +370,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
_dest_ptr = (uint8_t *)_ch_data[_ch_fraction][index0].lbp[index1] + offset;
|
||||
|
||||
uint8_t *dp_tmp = (uint8_t *)_dest_ptr;
|
||||
uint8_t *sp_tmp = (uint8_t *)_src_ptr;
|
||||
uint8_t *sp_tmp = (uint8_t *)data_src_ptr;
|
||||
while(len-- != 0) {
|
||||
*dp_tmp++ = *sp_tmp++;
|
||||
if (++_byte_fraction == ScaleSize) {
|
||||
@@ -380,79 +383,6 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic)
|
||||
}
|
||||
}
|
||||
|
||||
void LogicSnapshot::append_split_payload(const sr_datafeed_logic &logic)
|
||||
{
|
||||
assert(logic.format == LA_SPLIT_DATA);
|
||||
|
||||
uint64_t samples = logic.length * 8;
|
||||
uint16_t order = logic.order;
|
||||
assert(order < _ch_data.size());
|
||||
|
||||
if (_sample_cnt[order] >= _total_sample_count)
|
||||
return;
|
||||
|
||||
if (_sample_cnt[order] + samples < _total_sample_count) {
|
||||
_sample_cnt[order] += samples;
|
||||
} else {
|
||||
samples = _total_sample_count - _sample_cnt[order];
|
||||
_sample_cnt[order] = _total_sample_count;
|
||||
}
|
||||
|
||||
while (_sample_cnt[order] > _block_cnt[order] * LeafBlockSamples) {
|
||||
uint8_t index0 = _block_cnt[order] / RootScale;
|
||||
uint8_t index1 = _block_cnt[order] % RootScale;
|
||||
|
||||
if (_ch_data[order][index0].lbp[index1] == NULL)
|
||||
{
|
||||
_ch_data[order][index0].lbp[index1] = malloc(LeafBlockSpace);
|
||||
if (_ch_data[order][index0].lbp[index1] == NULL)
|
||||
{
|
||||
_memory_failed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memset(_ch_data[order][index0].lbp[index1], 0, LeafBlockSpace);
|
||||
_block_cnt[order]++;
|
||||
}
|
||||
|
||||
while(samples > 0) {
|
||||
const uint64_t index0 = _ring_sample_cnt[order] / RootNodeSamples;
|
||||
const uint64_t index1 = (_ring_sample_cnt[order] >> LeafBlockPower) % RootScale;
|
||||
const uint64_t offset = (_ring_sample_cnt[order] % LeafBlockSamples) / 8;
|
||||
_dest_ptr = (uint8_t *)_ch_data[order][index0].lbp[index1] + offset;
|
||||
|
||||
uint64_t bblank = (LeafBlockSamples - (_ring_sample_cnt[order] & LeafMask));
|
||||
if (samples >= bblank) {
|
||||
memcpy((uint8_t*)_dest_ptr, (uint8_t *)logic.data, bblank/8);
|
||||
_ring_sample_cnt[order] += bblank;
|
||||
samples -= bblank;
|
||||
|
||||
// calc mipmap of current block
|
||||
calc_mipmap(order, index0, index1, LeafBlockSamples);
|
||||
|
||||
// calc root of current block
|
||||
if (*((uint64_t *)_ch_data[order][index0].lbp[index1]) != 0)
|
||||
_ch_data[order][index0].value += 1ULL<< index1;
|
||||
if (*((uint64_t *)_ch_data[order][index0].lbp[index1] + LeafBlockSpace / sizeof(uint64_t) - 1) != 0) {
|
||||
_ch_data[order][index0].tog += 1ULL << index1;
|
||||
|
||||
} else {
|
||||
// trim leaf to free space
|
||||
free(_ch_data[order][index0].lbp[index1]);
|
||||
_ch_data[order][index0].lbp[index1] = NULL;
|
||||
}
|
||||
} else {
|
||||
memcpy((uint8_t*)_dest_ptr, (uint8_t *)logic.data, samples/8);
|
||||
_ring_sample_cnt[order] += samples;
|
||||
samples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_sample_count = array::find_min_uint64(_sample_cnt, _channel_num);
|
||||
_ring_sample_count = array::find_min_uint64(_ring_sample_cnt, _channel_num);
|
||||
}
|
||||
|
||||
void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples)
|
||||
{
|
||||
uint8_t offset;
|
||||
@@ -485,8 +415,7 @@ void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t inde
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_sample,
|
||||
int sig_index)
|
||||
const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_sample, int sig_index)
|
||||
{
|
||||
uint64_t sample_count = get_sample_count();
|
||||
assert(start_sample < sample_count);
|
||||
@@ -496,6 +425,7 @@ const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_s
|
||||
int order = get_ch_order(sig_index);
|
||||
uint64_t root_index = start_sample >> (LeafBlockPower + RootScalePower);
|
||||
uint8_t root_pos = (start_sample & RootMask) >> LeafBlockPower;
|
||||
|
||||
uint64_t block_offset = (start_sample & LeafMask) / 8;
|
||||
end_sample = (root_index << (LeafBlockPower + RootScalePower)) +
|
||||
(root_pos << LeafBlockPower) +
|
||||
@@ -520,8 +450,12 @@ bool LogicSnapshot::get_sample(uint64_t index, int sig_index)
|
||||
uint64_t root_index = index >> (LeafBlockPower + RootScalePower);
|
||||
uint8_t root_pos = (index & RootMask) >> LeafBlockPower;
|
||||
uint64_t root_pos_mask = 1ULL << root_pos;
|
||||
|
||||
uint64_t index0_r = _ring_sample_count >> (LeafBlockPower + RootScalePower);
|
||||
uint64_t index1_r = (_ring_sample_count >> LeafBlockPower) % RootScale;
|
||||
bool bAble = root_index < index0_r || (root_index == index0_r && root_pos <= index1_r);
|
||||
|
||||
if ((_ch_data[order][root_index].tog & root_pos_mask) == 0) {
|
||||
if (bAble && (_ch_data[order][root_index].tog & root_pos_mask) == 0) {
|
||||
return (_ch_data[order][root_index].value & root_pos_mask) != 0;
|
||||
} else {
|
||||
uint64_t *lbp = (uint64_t *)_ch_data[order][root_index].lbp[root_pos];
|
||||
@@ -589,9 +523,7 @@ bool LogicSnapshot::get_display_edges(std::vector<std::pair<bool, bool> > &edges
|
||||
return start_sample;
|
||||
}
|
||||
|
||||
bool LogicSnapshot::get_nxt_edge(
|
||||
uint64_t &index, bool last_sample, uint64_t end,
|
||||
double min_length, int sig_index)
|
||||
bool LogicSnapshot::get_nxt_edge(uint64_t &index, bool last_sample, uint64_t end, double min_length, int sig_index)
|
||||
{
|
||||
if (index > end)
|
||||
return false;
|
||||
@@ -607,30 +539,39 @@ bool LogicSnapshot::get_nxt_edge(
|
||||
bool edge_hit = false;
|
||||
|
||||
// linear search for the next transition on the root level
|
||||
for (int64_t i = root_index; !edge_hit && (index <= end) && i < (int64_t)_ch_data[order].size(); i++) {
|
||||
for (int64_t i = root_index; !edge_hit && (index <= end) && i < (int64_t)_ch_data[order].size(); i++)
|
||||
{
|
||||
uint64_t cur_mask = (~0ULL << root_pos);
|
||||
|
||||
do {
|
||||
uint64_t cur_tog = _ch_data[order][i].tog & cur_mask;
|
||||
|
||||
if (cur_tog != 0) {
|
||||
uint64_t first_edge_pos = bsf_folded(cur_tog);
|
||||
uint64_t *lbp = (uint64_t *)_ch_data[order][i].lbp[first_edge_pos];
|
||||
uint64_t blk_start = (i << (LeafBlockPower + RootScalePower)) + (first_edge_pos << LeafBlockPower);
|
||||
index = max(blk_start, index);
|
||||
|
||||
if (min_level < ScaleLevel) {
|
||||
uint64_t block_end = min(index | LeafMask, end);
|
||||
edge_hit = block_nxt_edge(lbp, index, block_end, last_sample, min_level);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
edge_hit = true;
|
||||
}
|
||||
|
||||
if (first_edge_pos == RootScale - 1)
|
||||
break;
|
||||
cur_mask = (~0ULL << (first_edge_pos + 1));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
index = (index + (1 << (LeafBlockPower + RootScalePower))) &
|
||||
(~0ULL << (LeafBlockPower + RootScalePower));
|
||||
break;
|
||||
}
|
||||
} while (!edge_hit && index < end);
|
||||
}
|
||||
while (!edge_hit && index < end);
|
||||
|
||||
root_pos = 0;
|
||||
}
|
||||
return edge_hit;
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#define CHANNEL_MAX_COUNT 128
|
||||
#define LOGIC_TMP_BUF_MAX_SIZE 512
|
||||
#define CHANNEL_MAX_COUNT 512
|
||||
|
||||
namespace LogicSnapshotTest {
|
||||
class Pow2;
|
||||
@@ -126,7 +125,6 @@ private:
|
||||
void calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples);
|
||||
|
||||
void append_cross_payload(const sr_datafeed_logic &logic);
|
||||
void append_split_payload(const sr_datafeed_logic &logic);
|
||||
|
||||
bool block_nxt_edge(uint64_t *lbp, uint64_t &index, uint64_t block_end, bool last_sample,
|
||||
unsigned int min_level);
|
||||
@@ -190,13 +188,12 @@ private:
|
||||
uint64_t _block_num;
|
||||
uint8_t _byte_fraction;
|
||||
uint16_t _ch_fraction;
|
||||
void *_src_ptr;
|
||||
void *_dest_ptr;
|
||||
|
||||
uint64_t _sample_cnt[LOGIC_TMP_BUF_MAX_SIZE];
|
||||
uint64_t _block_cnt[LOGIC_TMP_BUF_MAX_SIZE];
|
||||
uint64_t _ring_sample_cnt[LOGIC_TMP_BUF_MAX_SIZE];
|
||||
uint64_t _last_sample[LOGIC_TMP_BUF_MAX_SIZE];
|
||||
uint64_t _sample_cnt[CHANNEL_MAX_COUNT];
|
||||
uint64_t _block_cnt[CHANNEL_MAX_COUNT];
|
||||
uint64_t _ring_sample_cnt[CHANNEL_MAX_COUNT];
|
||||
uint64_t _last_sample[CHANNEL_MAX_COUNT];
|
||||
|
||||
friend class LogicSnapshotTest::Pow2;
|
||||
friend class LogicSnapshotTest::Basic;
|
||||
|
||||
@@ -44,7 +44,6 @@ Snapshot::Snapshot(int unit_size, uint64_t total_sample_count, unsigned int chan
|
||||
_unit_bytes = 1;
|
||||
_unit_pitch = 0;
|
||||
_have_data = false;
|
||||
_real_sample_count = 0;
|
||||
}
|
||||
|
||||
Snapshot::~Snapshot()
|
||||
@@ -59,7 +58,6 @@ void Snapshot::free_data()
|
||||
_data = NULL;
|
||||
_capacity = 0;
|
||||
_sample_count = 0;
|
||||
_real_sample_count = 0;
|
||||
}
|
||||
_ch_index.clear();
|
||||
}
|
||||
@@ -75,13 +73,7 @@ bool Snapshot::empty()
|
||||
uint64_t Snapshot::get_sample_count()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
//return _sample_count;
|
||||
// /*
|
||||
if (_real_sample_count > 0)
|
||||
return _real_sample_count;
|
||||
else
|
||||
return _sample_count;
|
||||
// */
|
||||
return _sample_count;
|
||||
}
|
||||
|
||||
uint64_t Snapshot::get_ring_start()
|
||||
|
||||
@@ -99,7 +99,6 @@ protected:
|
||||
uint64_t _capacity;
|
||||
unsigned int _channel_num;
|
||||
uint64_t _sample_count;
|
||||
uint64_t _real_sample_count;
|
||||
uint64_t _total_sample_count;
|
||||
uint64_t _ring_sample_count;
|
||||
int _unit_size;
|
||||
|
||||
@@ -96,6 +96,8 @@ static void get_file_short_name(const char *file, char *buf, int buflen)
|
||||
*wr = '\0';
|
||||
}
|
||||
|
||||
struct session_packet_buffer;
|
||||
|
||||
struct session_vdev
|
||||
{
|
||||
int version;
|
||||
@@ -122,6 +124,22 @@ struct session_vdev
|
||||
uint32_t ref_max;
|
||||
uint8_t max_height;
|
||||
struct sr_status mstatus;
|
||||
struct session_packet_buffer *packet_buffer;
|
||||
};
|
||||
|
||||
#define SESSION_MAX_CHANNEL_COUNT 512
|
||||
|
||||
struct session_packet_buffer
|
||||
{
|
||||
void *post_buf;
|
||||
uint64_t post_buf_len;
|
||||
uint64_t post_len;
|
||||
|
||||
uint64_t block_buf_len;
|
||||
uint64_t block_chan_read_pos;
|
||||
uint64_t block_data_len;
|
||||
void *block_bufs[SESSION_MAX_CHANNEL_COUNT];
|
||||
uint64_t block_poss[SESSION_MAX_CHANNEL_COUNT];
|
||||
};
|
||||
|
||||
static const int hwoptions[] = {
|
||||
@@ -234,7 +252,7 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi)
|
||||
assert(sdi->priv);
|
||||
|
||||
(void)fd;
|
||||
//(void)revents;
|
||||
(void)revents;
|
||||
|
||||
sr_detail("Feed chunk.");
|
||||
|
||||
@@ -242,150 +260,145 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi)
|
||||
packet.status = SR_PKT_OK;
|
||||
|
||||
vdev = sdi->priv;
|
||||
|
||||
assert(vdev->unit_bits > 0);
|
||||
assert(vdev->cur_channel >= 0);
|
||||
assert(vdev->archive);
|
||||
|
||||
if (vdev != NULL)
|
||||
if (vdev->cur_channel < vdev->num_probes)
|
||||
{
|
||||
assert(vdev->unit_bits > 0);
|
||||
assert(vdev->cur_channel >= 0);
|
||||
assert(vdev->archive);
|
||||
|
||||
if (vdev->cur_channel < vdev->num_probes)
|
||||
if (vdev->version == 1)
|
||||
{
|
||||
if (vdev->version == 1)
|
||||
ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE);
|
||||
if (-1 == ret)
|
||||
{
|
||||
sr_err("%s: Read inner file error!", __func__);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (vdev->version == 2)
|
||||
{
|
||||
channel = vdev->cur_channel;
|
||||
pl = sdi->channels;
|
||||
|
||||
while (channel--){
|
||||
pl = pl->next;
|
||||
}
|
||||
|
||||
probe = (struct sr_channel *)pl->data;
|
||||
|
||||
if (vdev->capfile == 0)
|
||||
{
|
||||
char *type_name = (probe->type == SR_CHANNEL_LOGIC) ? "L" : (probe->type == SR_CHANNEL_DSO) ? "O"
|
||||
: (probe->type == SR_CHANNEL_ANALOG) ? "A"
|
||||
: "U";
|
||||
|
||||
snprintf(file_name, sizeof(file_name)-1, "%s-%d/%d", type_name,
|
||||
sdi->mode == LOGIC ? probe->index : 0, vdev->cur_block);
|
||||
|
||||
if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK)
|
||||
{
|
||||
sr_err("cant't locate zip inner file:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
if (unzOpenCurrentFile(vdev->archive) != UNZ_OK)
|
||||
{
|
||||
sr_err("cant't open zip inner file:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
vdev->capfile = 1;
|
||||
}
|
||||
|
||||
if (vdev->capfile)
|
||||
{
|
||||
ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE);
|
||||
|
||||
if (-1 == ret)
|
||||
{
|
||||
sr_err("%s: Read inner file error!", __func__);
|
||||
sr_err("read zip inner file error:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (vdev->version == 2)
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
if (sdi->mode == DSO)
|
||||
{
|
||||
channel = vdev->cur_channel;
|
||||
pl = sdi->channels;
|
||||
|
||||
while (channel--)
|
||||
pl = pl->next;
|
||||
|
||||
probe = (struct sr_channel *)pl->data;
|
||||
|
||||
if (vdev->capfile == 0)
|
||||
{
|
||||
char *type_name = (probe->type == SR_CHANNEL_LOGIC) ? "L" : (probe->type == SR_CHANNEL_DSO) ? "O"
|
||||
: (probe->type == SR_CHANNEL_ANALOG) ? "A"
|
||||
: "U";
|
||||
|
||||
snprintf(file_name, 31, "%s-%d/%d", type_name,
|
||||
sdi->mode == LOGIC ? probe->index : 0, vdev->cur_block);
|
||||
|
||||
if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK)
|
||||
{
|
||||
sr_err("cant't locate zip inner file:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
if (unzOpenCurrentFile(vdev->archive) != UNZ_OK)
|
||||
{
|
||||
sr_err("cant't open zip inner file:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
vdev->capfile = 1;
|
||||
}
|
||||
|
||||
if (vdev->capfile)
|
||||
{
|
||||
ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE);
|
||||
|
||||
if (-1 == ret)
|
||||
{
|
||||
sr_err("read zip inner file error:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
packet.type = SR_DF_DSO;
|
||||
packet.payload = &dso;
|
||||
dso.num_samples = ret / vdev->num_probes;
|
||||
dso.data = vdev->buf;
|
||||
dso.probes = sdi->channels;
|
||||
dso.mq = SR_MQ_VOLTAGE;
|
||||
dso.unit = SR_UNIT_VOLT;
|
||||
dso.mqflags = SR_MQFLAG_AC;
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
else if (sdi->mode == ANALOG)
|
||||
{
|
||||
if (sdi->mode == DSO)
|
||||
{
|
||||
packet.type = SR_DF_DSO;
|
||||
packet.payload = &dso;
|
||||
dso.num_samples = ret / vdev->num_probes;
|
||||
dso.data = vdev->buf;
|
||||
dso.probes = sdi->channels;
|
||||
dso.mq = SR_MQ_VOLTAGE;
|
||||
dso.unit = SR_UNIT_VOLT;
|
||||
dso.mqflags = SR_MQFLAG_AC;
|
||||
}
|
||||
else if (sdi->mode == ANALOG)
|
||||
{
|
||||
packet.type = SR_DF_ANALOG;
|
||||
packet.payload = &analog;
|
||||
analog.probes = sdi->channels;
|
||||
analog.num_samples = ret / vdev->num_probes / ((vdev->unit_bits + 7) / 8);
|
||||
analog.unit_bits = vdev->unit_bits;
|
||||
analog.mq = SR_MQ_VOLTAGE;
|
||||
analog.unit = SR_UNIT_VOLT;
|
||||
analog.mqflags = SR_MQFLAG_AC;
|
||||
analog.data = vdev->buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.type = SR_DF_LOGIC;
|
||||
packet.payload = &logic;
|
||||
logic.length = ret;
|
||||
logic.format = (vdev->version == 2) ? LA_SPLIT_DATA : LA_CROSS_DATA;
|
||||
if (probe)
|
||||
logic.index = probe->index;
|
||||
else
|
||||
logic.index = 0;
|
||||
logic.order = vdev->cur_channel;
|
||||
|
||||
if (vdev->version == 1)
|
||||
{
|
||||
logic.length = ret / 16 * vdev->enabled_probes;
|
||||
logic.data = vdev->logic_buf;
|
||||
trans_data(sdi);
|
||||
}
|
||||
else if (vdev->version == 2)
|
||||
{
|
||||
logic.length = ret;
|
||||
logic.data = vdev->buf;
|
||||
}
|
||||
}
|
||||
|
||||
vdev->bytes_read += ret;
|
||||
ds_data_forward(sdi, &packet);
|
||||
packet.type = SR_DF_ANALOG;
|
||||
packet.payload = &analog;
|
||||
analog.probes = sdi->channels;
|
||||
analog.num_samples = ret / vdev->num_probes / ((vdev->unit_bits + 7) / 8);
|
||||
analog.unit_bits = vdev->unit_bits;
|
||||
analog.mq = SR_MQ_VOLTAGE;
|
||||
analog.unit = SR_UNIT_VOLT;
|
||||
analog.mqflags = SR_MQFLAG_AC;
|
||||
analog.data = vdev->buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* done with this capture file */
|
||||
unzCloseCurrentFile(vdev->archive);
|
||||
vdev->capfile = 0;
|
||||
|
||||
if (vdev->version == 1)
|
||||
{
|
||||
vdev->cur_channel++;
|
||||
if (vdev->version == 2){
|
||||
assert(0);
|
||||
}
|
||||
else if (vdev->version == 2)
|
||||
|
||||
packet.type = SR_DF_LOGIC;
|
||||
packet.payload = &logic;
|
||||
logic.length = ret;
|
||||
logic.format = LA_CROSS_DATA;
|
||||
if (probe)
|
||||
logic.index = probe->index;
|
||||
else
|
||||
logic.index = 0;
|
||||
logic.order = vdev->cur_channel;
|
||||
|
||||
//version == 1
|
||||
logic.length = ret / 16 * vdev->enabled_probes;
|
||||
logic.data = vdev->logic_buf;
|
||||
trans_data(sdi);
|
||||
}
|
||||
|
||||
vdev->bytes_read += ret;
|
||||
ds_data_forward(sdi, &packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* done with this capture file */
|
||||
unzCloseCurrentFile(vdev->archive);
|
||||
vdev->capfile = 0;
|
||||
|
||||
if (vdev->version == 1)
|
||||
{
|
||||
vdev->cur_channel++;
|
||||
}
|
||||
else if (vdev->version == 2)
|
||||
{
|
||||
vdev->cur_block++;
|
||||
// if read to the last block, move to next channel
|
||||
if (vdev->cur_block == vdev->num_blocks)
|
||||
{
|
||||
vdev->cur_block++;
|
||||
// if read to the last block, move to next channel
|
||||
if (vdev->cur_block == vdev->num_blocks)
|
||||
{
|
||||
vdev->cur_block = 0;
|
||||
vdev->cur_channel++;
|
||||
}
|
||||
vdev->cur_block = 0;
|
||||
vdev->cur_channel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!vdev || vdev->cur_channel >= vdev->num_probes || revents == -1)
|
||||
if (vdev->cur_channel >= vdev->num_probes || revents == -1)
|
||||
{
|
||||
packet.type = SR_DF_END;
|
||||
ds_data_forward(sdi, &packet);
|
||||
@@ -402,6 +415,222 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int receive_data_logic2(int fd, int revents, const struct sr_dev_inst *sdi)
|
||||
{
|
||||
struct session_vdev *vdev = NULL;
|
||||
struct sr_datafeed_packet packet;
|
||||
struct sr_datafeed_logic logic;
|
||||
struct sr_datafeed_dso dso;
|
||||
struct sr_datafeed_analog analog;
|
||||
GSList *l;
|
||||
int ret;
|
||||
char file_name[32];
|
||||
GSList *pl;
|
||||
int channel;
|
||||
int ch_index, ch_index2;
|
||||
struct session_packet_buffer *pack_buffer;
|
||||
unz_file_info64 fileInfo;
|
||||
char szFilePath[15];
|
||||
int bToEnd;
|
||||
int chIndex;
|
||||
int chan_num;
|
||||
void *p_wr;
|
||||
void *p_rd;
|
||||
|
||||
assert(sdi);
|
||||
assert(sdi->priv);
|
||||
|
||||
(void)fd;
|
||||
(void)revents;
|
||||
|
||||
sr_detail("Feed chunk.");
|
||||
|
||||
ret = 0;
|
||||
bToEnd = 0;
|
||||
packet.status = SR_PKT_OK;
|
||||
|
||||
vdev = sdi->priv;
|
||||
|
||||
assert(vdev->unit_bits > 0);
|
||||
assert(vdev->archive);
|
||||
|
||||
chan_num = vdev->num_probes;
|
||||
|
||||
if (chan_num < 1){
|
||||
sr_err("%s: channel count < 1.", __func__);
|
||||
return SR_ERR_ARG;
|
||||
}
|
||||
|
||||
if (vdev->packet_buffer == NULL){
|
||||
vdev->cur_block = 0;
|
||||
|
||||
vdev->packet_buffer = g_try_malloc0(sizeof(struct session_packet_buffer));
|
||||
if (vdev->packet_buffer == NULL){
|
||||
sr_err("%s: vdev->packet_buffer malloc failed", __func__);
|
||||
return SR_ERR_MALLOC;
|
||||
}
|
||||
|
||||
for (ch_index = 0; ch_index < SESSION_MAX_CHANNEL_COUNT; ch_index++){
|
||||
vdev->packet_buffer->block_bufs[ch_index] = NULL;
|
||||
vdev->packet_buffer->block_poss[ch_index] = 0;
|
||||
}
|
||||
|
||||
vdev->packet_buffer->post_buf_len = 8 * chan_num * 1000;
|
||||
vdev->packet_buffer->post_buf = g_try_malloc0(vdev->packet_buffer->post_buf_len + 1);
|
||||
if (vdev->packet_buffer->post_buf == NULL){
|
||||
sr_err("%s: vdev->packet_buffer->post_buf malloc failed", __func__);
|
||||
return SR_ERR_MALLOC;
|
||||
}
|
||||
|
||||
pack_buffer = vdev->packet_buffer;
|
||||
pack_buffer->post_len;
|
||||
pack_buffer->block_buf_len = 0;
|
||||
pack_buffer->block_data_len = 0;
|
||||
pack_buffer->block_chan_read_pos = 0;
|
||||
}
|
||||
pack_buffer = vdev->packet_buffer;
|
||||
|
||||
// Make packet.
|
||||
chIndex = 0;
|
||||
|
||||
while (pack_buffer->post_len < pack_buffer->post_buf_len)
|
||||
{
|
||||
if (pack_buffer->block_chan_read_pos >= pack_buffer->block_data_len)
|
||||
{
|
||||
if (vdev->cur_block >= vdev->num_blocks){
|
||||
bToEnd = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (ch_index = 0; ch_index < chan_num; ch_index++)
|
||||
{
|
||||
snprintf(file_name, sizeof(file_name)-1, "%s-%d/%d", "L",
|
||||
ch_index, vdev->cur_block);
|
||||
|
||||
if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK)
|
||||
{
|
||||
sr_err("cant't locate zip inner file:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (unzGetCurrentFileInfo64(vdev->archive, &fileInfo, szFilePath,
|
||||
sizeof(szFilePath), NULL, 0, NULL, 0) != UNZ_OK)
|
||||
{
|
||||
sr_err("%s: unzGetCurrentFileInfo64 error.", __func__);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ch_index == 0){
|
||||
pack_buffer->block_data_len = fileInfo.uncompressed_size;
|
||||
|
||||
if (pack_buffer->block_data_len > pack_buffer->block_buf_len){
|
||||
for (ch_index2 = 0; ch_index2 < chan_num; ch_index2++)
|
||||
{
|
||||
// Release the old buffer.
|
||||
if (pack_buffer->block_bufs[ch_index2] != NULL){
|
||||
g_free(pack_buffer->block_bufs[ch_index2]);
|
||||
pack_buffer->block_bufs[ch_index2] = NULL;
|
||||
}
|
||||
|
||||
pack_buffer->block_bufs[ch_index2] = g_try_malloc0(pack_buffer->block_data_len + 1);
|
||||
if (pack_buffer->block_bufs[ch_index2] == NULL){
|
||||
sr_err("%s: block buffer malloc failed", __func__);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
pack_buffer->block_buf_len = pack_buffer->block_data_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pack_buffer->block_data_len != fileInfo.uncompressed_size){
|
||||
sr_err("The block size is not coincident:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the data to buffer.
|
||||
if (unzOpenCurrentFile(vdev->archive) != UNZ_OK)
|
||||
{
|
||||
sr_err("cant't open zip inner file:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = unzReadCurrentFile(vdev->archive, pack_buffer->block_bufs[ch_index], pack_buffer->block_data_len);
|
||||
if (-1 == ret)
|
||||
{
|
||||
sr_err("read zip inner file error:%s", file_name);
|
||||
send_error_packet(sdi, vdev, &packet);
|
||||
return FALSE;
|
||||
}
|
||||
unzCloseCurrentFile(vdev->archive);
|
||||
pack_buffer->block_poss[ch_index] = 0; // Reset the read position.
|
||||
}
|
||||
|
||||
vdev->cur_block++;
|
||||
pack_buffer->block_chan_read_pos = 0;
|
||||
}
|
||||
|
||||
p_wr = (pack_buffer->post_buf + pack_buffer->post_len);
|
||||
p_rd = (pack_buffer->block_bufs[chIndex] + pack_buffer->block_poss[chIndex]);
|
||||
*(uint8_t*)p_wr = *(uint8_t*)p_rd;
|
||||
|
||||
pack_buffer->post_len++;
|
||||
pack_buffer->block_poss[chIndex]++;
|
||||
|
||||
if (pack_buffer->block_poss[chIndex] % 8 == 0
|
||||
|| pack_buffer->block_poss[chIndex] == pack_buffer->block_data_len)
|
||||
{
|
||||
chIndex++;
|
||||
|
||||
if (pack_buffer->block_poss[chIndex] == pack_buffer->block_data_len){
|
||||
sr_info("Block read end.");
|
||||
if (vdev->cur_block < vdev->num_blocks){
|
||||
sr_err("%s", "The block data is not align.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (chIndex == chan_num){
|
||||
chIndex = 0;
|
||||
pack_buffer->block_chan_read_pos += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pack_buffer->post_len >= 8 * chan_num)
|
||||
{
|
||||
packet.type = SR_DF_LOGIC;
|
||||
packet.payload = &logic;
|
||||
logic.format = LA_CROSS_DATA;
|
||||
logic.index = 0;
|
||||
logic.order = 0;
|
||||
|
||||
logic.length = pack_buffer->post_len;
|
||||
logic.data = pack_buffer->post_buf;
|
||||
|
||||
vdev->bytes_read += ret;
|
||||
ds_data_forward(sdi, &packet);
|
||||
pack_buffer->post_len = 0;
|
||||
}
|
||||
|
||||
if (bToEnd || revents == -1)
|
||||
{
|
||||
packet.type = SR_DF_END;
|
||||
ds_data_forward(sdi, &packet);
|
||||
sr_session_source_remove(-1);
|
||||
close_archive(vdev);
|
||||
vdev->bytes_read = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* driver callbacks */
|
||||
static int dev_clear(void);
|
||||
|
||||
@@ -453,13 +682,7 @@ static int dev_open(struct sr_dev_inst *sdi)
|
||||
}
|
||||
vdev = sdi->priv;
|
||||
|
||||
vdev->buf = g_try_malloc(CHUNKSIZE + sizeof(uint64_t));
|
||||
if (vdev->buf == NULL)
|
||||
{
|
||||
sr_err("%s: vdev->buf malloc failed", __func__);
|
||||
return SR_ERR_MALLOC;
|
||||
}
|
||||
|
||||
vdev->buf = NULL;
|
||||
vdev->trig_pos = 0;
|
||||
vdev->trig_time = 0;
|
||||
vdev->cur_block = 0;
|
||||
@@ -474,9 +697,16 @@ static int dev_open(struct sr_dev_inst *sdi)
|
||||
vdev->mstatus.measure_valid = TRUE;
|
||||
vdev->archive = NULL;
|
||||
vdev->capfile = 0;
|
||||
|
||||
vdev->packet_buffer = NULL;
|
||||
vdev->logic_buf = NULL;
|
||||
sdi->status = SR_ST_ACTIVE;
|
||||
|
||||
vdev->buf = g_try_malloc(CHUNKSIZE + sizeof(uint64_t));
|
||||
if (vdev->buf == NULL){
|
||||
sr_err("%s: vdev->buf malloc failed", __func__);
|
||||
return SR_ERR_MALLOC;
|
||||
}
|
||||
|
||||
ret = sr_load_virtual_device_session(sdi);
|
||||
if (ret != SR_OK)
|
||||
{
|
||||
@@ -490,10 +720,27 @@ static int dev_open(struct sr_dev_inst *sdi)
|
||||
static int dev_close(struct sr_dev_inst *sdi)
|
||||
{
|
||||
struct session_vdev *vdev;
|
||||
int i;
|
||||
struct session_packet_buffer *pack_buf;
|
||||
|
||||
if (sdi && sdi->priv)
|
||||
{
|
||||
vdev = sdi->priv;
|
||||
|
||||
if (vdev->packet_buffer != NULL){
|
||||
pack_buf = vdev->packet_buffer;
|
||||
|
||||
g_safe_free(pack_buf->post_buf);
|
||||
|
||||
for (i = 0; i < SESSION_MAX_CHANNEL_COUNT; i++){
|
||||
if (pack_buf->block_bufs[i] != NULL){
|
||||
g_free(pack_buf->block_bufs[i]);
|
||||
pack_buf->block_bufs[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_safe_free(vdev->packet_buffer);
|
||||
g_safe_free(vdev->buf);
|
||||
g_safe_free(vdev->logic_buf);
|
||||
g_safe_free(sdi->priv);
|
||||
@@ -1126,7 +1373,12 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data)
|
||||
}
|
||||
|
||||
/* freewheeling source */
|
||||
sr_session_source_add(-1, 0, 0, receive_data, sdi);
|
||||
if (sdi->mode == LOGIC && vdev->version == 2){
|
||||
sr_session_source_add(-1, 0, 0, receive_data_logic2, sdi);
|
||||
}
|
||||
else{
|
||||
sr_session_source_add(-1, 0, 0, receive_data, sdi);
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user