Re: ngene CI problems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux