Re: VDR continuously initializing CAM

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

 



Klaus Schmidinger wrote:
At this point...

Apr  7 09:06:41 vdr vdr: [4862] ms: 3
Apr  7 09:06:41 vdr vdr: [4862] resetTime1: 0
Apr  7 09:06:41 vdr vdr: [4862] ms: 2

...the module status changed from 3 ("ready") to 2 ("present").
The module status is retrieved from the driver in cDvbCiAdapter::ModuleStatus():

eModuleStatus cDvbCiAdapter::ModuleStatus(int Slot)
{
   ca_slot_info_t sinfo;
   sinfo.num = Slot;
   if (ioctl(fd, CA_GET_SLOT_INFO, &sinfo) != -1) {
      if ((sinfo.flags & CA_CI_MODULE_READY) != 0)
         return msReady;
      else if ((sinfo.flags & CA_CI_MODULE_PRESENT) != 0)
         return msPresent;
      }
   else
      esyslog("ERROR: can't get info of CAM slot %d on device %d: %m", Slot, device->DeviceNumber());
   return msNone;
}

So for some reason the sinfo.flags doesn't seem to have the CA_CI_MODULE_READY
flag set any longer.

Please take a look to the test code in attachment, provided by Christoph Pfister. With it I got the following output:

root@vdr:/video/vdr/cam# ./test
0.000008: 3
0.000161: 0
0.014133: 1
1.694142: 3

And explanation:
After a reset CAM is "absent" for a very short time (<14ms == less than a scheduler tick) and then it takes ~1.7s to become ready again. (The intervall between reset and status query seems to be a bit bigger in vdr - so we only see the 3-->1 change == 3-->2 in vdr numbers).

It's an endless loop: cam detection --> cam reset --> cam not present/ready for a short while --> vdr thinks cam has been physically
removed --> cam detection --> cam reset etc.

Big thanks to Christoph for assistance.

Is it realistic to hope for a workaround/solution for this kind of CAMs (Technotrend CX at my case)?

Regards,
AK
#include <fcntl.h>
#include <linux/dvb/ca.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <unistd.h>

int cam_status(int fd)
{
	ca_slot_info_t info;
	memset(&info, 0, sizeof(info));
	info.num = 0;

	if (ioctl(fd, CA_GET_SLOT_INFO, &info) != 0) {
		printf("error: couldn't get slot info\n");
		return -1;
	}

	return info.flags;
}

struct timeval start_time;

void print_status(int status)
{
	struct timeval time;
	gettimeofday(&time, NULL);

	int dsec = time.tv_sec - start_time.tv_sec;
	int dusec = time.tv_usec - start_time.tv_usec;

	if (dusec < 0) {
		dusec += 1000000;
		dsec -= 1;
	}

	printf("%i.%06i: %i\n", dsec, dusec, status);
}

int main()
{
	int fd = open("/dev/dvb/adapter0/ca0", O_RDWR);

	if (fd < 0) {
		printf("error: couldn't open ca handle\n");
		return 1;
	}

	gettimeofday(&start_time, NULL);

	int status = cam_status(fd);
	print_status(status);

	if (ioctl(fd, CA_RESET, (1 << 0)) != 0) {
		printf("error: couldn't reset cam\n");
		return 1;
	}

	int i;
	for (i = 0; i < 200; ++i) {
		int new_status = cam_status(fd);

		if (status != new_status) {
			status = new_status;
			print_status(status);
		}

		usleep(10000);
	}

	return 0;
}
_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux