142 lines
3.8 KiB
C
142 lines
3.8 KiB
C
|
|
#include <stdio.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
|
|
|
|
struct vbi_data_s {
|
|
unsigned int vbi_type:8;
|
|
unsigned int field_id:8;
|
|
unsigned int tt_sys:8;/*tt*/
|
|
unsigned int nbytes:16;
|
|
unsigned int line_num:16;
|
|
unsigned char b[42]; /* 42 for TT-625B */
|
|
};
|
|
|
|
#define VBI_IOC_MAGIC 'X'
|
|
#define VBI_IOC_START _IO(VBI_IOC_MAGIC, 0x05)
|
|
#define VBI_IOC_SET_TYPE _IOW(VBI_IOC_MAGIC, 0x03, int)
|
|
|
|
#define VBI_POLL_TIMEOUT 16
|
|
|
|
static void *ds_vbi_read_task(void *args)
|
|
{
|
|
reader_inst_t *inst = (reader_inst_t *)args;
|
|
struct vbi_data_s vbi[50];
|
|
|
|
ds_inf("vbi read task started");
|
|
|
|
if (ioctl(inst->fd, VBI_IOC_START) == -1) {
|
|
ds_err("VBI_IOC_START error(%d:%s)", errno, strerror(errno));
|
|
}
|
|
|
|
while (inst->running) {
|
|
|
|
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, VBI_POLL_TIMEOUT);
|
|
|
|
if (inst->running && ret > 0 && pfd[0].events & POLLIN) {
|
|
struct vbi_data_s *pd;
|
|
|
|
ret = read(inst->fd, vbi, sizeof(vbi));
|
|
pd = vbi;
|
|
|
|
if (ret >= (int)sizeof(struct vbi_data_s)) {
|
|
while (inst->running && ret >= (int)sizeof(struct vbi_data_s)) {
|
|
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 *)pd, sizeof(struct vbi_data_s), cb->priv);
|
|
cb->fn.ready_cb(1/*blk mode*/, sizeof(struct vbi_data_s), cb->priv);
|
|
}
|
|
|
|
pthread_mutex_unlock(&inst->callback_list_lock);
|
|
|
|
pd++;
|
|
ret -= sizeof(struct vbi_data_s);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ds_inf("vbi read task exit");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ds_vbi_set(reader_inst_t *inst, const char *settings)
|
|
{
|
|
int ret = 0;
|
|
|
|
char *set = "src_para_vbi_type";
|
|
int len = strlen(set);
|
|
|
|
if (!settings)
|
|
return ret;
|
|
|
|
if (strncmp(settings, set, len) == 0) {
|
|
int type;
|
|
if (sscanf(settings, "%*s %d", &type) == 1) {
|
|
if (ioctl(inst->fd, VBI_IOC_SET_TYPE, &type) == 0) {
|
|
ds_inf("VBI_IOC_SET_TYPE %d", type);
|
|
} else {
|
|
ds_err("VBI_IOC_SET_TYPE %d, error(%d:%s)",
|
|
type, errno, strerror(errno));
|
|
ret = -1;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static ds_reader_t vbi_reader = {
|
|
.task = ds_vbi_read_task,
|
|
.set = ds_vbi_set,
|
|
};
|
|
|
|
static ds_reader_t* ds_vbi_reader_check(const char *devname)
|
|
{
|
|
if (strcmp(devname, "/dev/vbi") == 0)
|
|
return &vbi_reader;
|
|
return NULL;
|
|
}
|
|
|
|
REG_DS_READER(ds_vbi_reader_check);
|
|
|