Hello Oliver, On Wed, 11 May 2011, Oliver Endriss wrote: > On Monday 07 March 2011 14:50:02 Martin Vidovic wrote: > > ... > > - SEC device generates NULL packets (ad infinitum): > > > > When reading from SEC, NULL packets are read and interleaved with > > expected packets. They can be even read with dd(1) when nobody is > > writing to SEC and even when CAM is not ready. > > ... > > I reworked the driver to strip those null packets. Please try > http://linuxtv.org/hg/~endriss/ngene-octopus-test/raw-rev/f0dc4237ad08 > a) Tested without CAM, it works OK. b) Tested with Viaccess Pocket dTV, there are some problems: Sometimes filtering works, sometimes it doesn't. This summarises the observed behaviour: (1) When I read 188 bytes from SEC, I notice first byte isn't 0x47. So, I count how many bytes need to be skipped to get to the 0x47 byte. For illustration, let's say 8 bytes need to be skipped. (2) Now I do CA_RESET ioctl on matching CA device and wait 3 seconds. (3) Repeat step (1) but now I count 4 bytes need to be skipped. (4) Do CA_RESET. (5) NULL packets can't be read now. (6) Do CA_RESET. (7) Repeat step (1) and now 184 bytes need to be skipped. (8) and so on... Here is the code I used for testing: #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <linux/dvb/ca.h> #include <stdio.h> #define NUM_PKT 672 #define BUF_SIZE (NUM_PKT * 188) int fd_ca = -1; int fd_sec = -1; unsigned char *buf_in = NULL; pthread_t read_thread; int err(const char *msg) { printf("ERROR: %s (%m).\n", msg); return 1; } void *read_thread_main(void *tparm) { ssize_t n_read = 0; size_t prev_sync_off = 0; size_t prev_sync_diff = 0; size_t i = 0; while (1) { n_read = read(fd_sec, buf_in, BUF_SIZE); if (n_read > 0) { printf("[%zd b]: ", n_read); prev_sync_off = 0; for (i = 1; i < n_read; i++) { if (buf_in[i] == 0x47) { /* measure distance between two sync bytes */ if ((i - prev_sync_off) != prev_sync_diff) { prev_sync_diff = (i - prev_sync_off); printf("%zu @ %zu; ", prev_sync_diff, i); } prev_sync_off = i; } } printf("\n"); } else if (n_read < 0) { printf("SEC read error '%m'.\n"); break; } } return NULL; } int main(int argc, char **argv) { char path_ca[] = "/dev/dvb/0123456789abcdef/ca0"; char path_sec[] = "/dev/dvb/0123456789abcdef/sec0"; /* make dev paths + malloc buffers */ if (argc != 2) { printf("usage: %s adapter_name\n", argv[0]); return 1; } if (strlen(argv[1]) > 16) return err("adapter name too long (max 16)"); sprintf(path_ca, "/dev/dvb/%s/ca0", argv[1]); sprintf(path_sec, "/dev/dvb/%s/sec0", argv[1]); buf_in = malloc(BUF_SIZE); if (buf_in == NULL) return err("malloc buf_in"); /* open devs */ fd_ca = open(path_ca, O_RDWR); if (fd_ca == -1) return err("open path_ca"); fd_sec = open(path_sec, O_RDWR); if (fd_sec == -1) return err("open path_sec"); /* start work */ if (pthread_create(&read_thread, NULL, &read_thread_main, NULL) != 0) return err("read_thread start failed."); pthread_detach(read_thread); /* CA reset loop */ while (1) { sleep(3); printf("\nCA reset\n\n"); ioctl(fd_ca, CA_RESET); } } Best regards, Martin Vidovic -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html