145 lines
3.3 KiB
C
145 lines
3.3 KiB
C
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <poll.h>
|
|
#include <unistd.h>
|
|
#include <sys/ioctl.h>
|
|
#include <linux/types.h>
|
|
|
|
#include "dataserver_reader_inner.h"
|
|
|
|
#ifdef LOG_LOGCAT
|
|
|
|
#define LOG_TAG "ccdataserver"
|
|
#include <log/log.h>
|
|
#define ds_inf(_fmt_,...) ALOGI("%s:%d "_fmt_, __func__, __LINE__, ##__VA_ARGS__)
|
|
#define ds_err(_fmt_,...) ALOGE("%s:%d "_fmt_, __func__, __LINE__, ##__VA_ARGS__)
|
|
|
|
#else
|
|
|
|
#define ds_inf(_fmt_,...) printf("I %s:%d "_fmt_"\n", __func__, __LINE__, ##__VA_ARGS__)
|
|
#define ds_err(_fmt_,...) printf("E %s:%d "_fmt_"\n", __func__, __LINE__, ##__VA_ARGS__)
|
|
|
|
#endif
|
|
|
|
|
|
#define RANDOM_POLL_TIMEOUT 1000
|
|
|
|
static int blk_size = 512;
|
|
|
|
static void *ds_random_read_task(void *args)
|
|
{
|
|
reader_inst_t *inst = (reader_inst_t *)args;
|
|
uint8_t *rand = (uint8_t *)malloc(blk_size);
|
|
|
|
ds_inf("random read [bs:%d] task started", blk_size);
|
|
|
|
while (inst->running && rand) {
|
|
|
|
struct pollfd pfd[2];
|
|
int ret;
|
|
|
|
pfd[0].fd = inst->fd;
|
|
pfd[1].fd = inst->evtfd;
|
|
pfd[0].events = pfd[1].events = POLLIN | POLLERR;
|
|
|
|
ret = poll(pfd, 2, RANDOM_POLL_TIMEOUT);
|
|
|
|
if (!inst->running)
|
|
break;
|
|
|
|
if (ret > 0 && pfd[0].events & POLLIN) {
|
|
|
|
ret = read(inst->fd, rand, blk_size);
|
|
|
|
if (ret) {
|
|
ds_data_callback_t *cb;
|
|
|
|
pthread_mutex_lock(&inst->callback_list_lock);
|
|
|
|
/*move the waiting callbacks to main list*/
|
|
if (!list_empty(&inst->callback_wait_list)) {
|
|
struct list_head *pos, *tmp;
|
|
list_for_each_safe(pos, tmp, &inst->callback_wait_list) {
|
|
list_del(pos);
|
|
list_add_tail(pos, &inst->callback_list);
|
|
}
|
|
}
|
|
|
|
list_for_each_entry(cb, &inst->callback_list, head) {
|
|
cb->fn.data_cb((uint8_t *)rand, ret, cb->priv);
|
|
cb->fn.ready_cb(1/*block mode*/, ret, cb->priv);
|
|
}
|
|
|
|
pthread_mutex_unlock(&inst->callback_list_lock);
|
|
}
|
|
}
|
|
|
|
/*as /dev/random is a fake device,
|
|
* slow down the data rate
|
|
*/
|
|
int i;
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
if (!inst->running)
|
|
break;
|
|
|
|
usleep(10 * 1000);/*10ms*/
|
|
}
|
|
}
|
|
|
|
if (rand) {
|
|
free(rand);
|
|
} else {
|
|
ds_err("memory fail");
|
|
}
|
|
|
|
ds_inf("random read task exit");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ds_random_set(reader_inst_t *inst, const char *settings)
|
|
{
|
|
(void)inst;
|
|
|
|
int ret = 0;
|
|
|
|
char *set = "src_para_random_bs";
|
|
int len = strlen(set);
|
|
|
|
if (!settings)
|
|
return ret;
|
|
|
|
if (strncmp(settings, set, len) == 0) {
|
|
int bs;
|
|
if (sscanf(settings, "%*s %d", &bs) == 1) {
|
|
if (bs >= 0) {
|
|
blk_size = bs;
|
|
} else {
|
|
ds_err("random bs set fail %d", bs);
|
|
ret = -1;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
static ds_reader_t random_reader = {
|
|
.task = ds_random_read_task,
|
|
.set = ds_random_set,
|
|
};
|
|
|
|
static ds_reader_t* ds_random_reader_check(const char *devname)
|
|
{
|
|
if (strcmp(devname, "/dev/random") == 0)
|
|
return &random_reader;
|
|
return NULL;
|
|
}
|
|
|
|
REG_DS_READER(ds_random_reader_check);
|
|
|