#include #include #include #include #include #include #include #include "dataserver_reader_inner.h" #ifdef LOG_LOGCAT #define LOG_TAG "ccdataserver" #include #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);