2
0
forked from Ivasoft/DSView

Load data in sections for each channel

This commit is contained in:
dreamsourcelabTAI
2022-11-30 19:43:52 +08:00
parent da6b8ff426
commit 258fa4dfd3
5 changed files with 437 additions and 256 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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()

View File

@@ -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;

View File

@@ -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;
}