Sehr viele Thread's hier im Board beschäftigen sich in letzter Zeit immer wieder mit dem einen Thema:
Nach dem flashen eines neuen Images kann trotz gültiger Karte kein Premiere mehr gesehen werden.
Wie wir leider doch noch nicht alle wissen ist in den fertigen Images der Premieresupport deaktiviert.
Viele User haben ihre Box schon vor längerer Zeit mit Linux gekauft und sind erst jetzt auf die Idee gekommen sich eine neues Image einzuspielen weil die neue Software doch so viel mehr kann als die alte.
Nach dem flashen hängt dann der Haussegen schief weil in einer halben Stunde "der Film" oder "das Fußballspiel" anfängt.
Die Suchfunktion des Board's hilft da in dieser Stresssituation nicht wirklich weiter.
Wenn man die Fragen kennt die man stellen müsste, um schnell die Antworten zu bekommen die man sucht, bräuchte man eigentlich nicht zu suchen.
Was meiner Meinung nach fehlt ist eine Fehlermeldung auf dem Fernseher!
Nach dem meine Frau vor einigen Tagen die Karte in den falschen Kartenslot gesteckt hatte, und ich doch einige Zeit gebraucht hatte um diesen simplen Fehler zu entdecken habe ich mich mal um eine Lösung bemüht.
Hier ist das (für mich ausreichende) Ergebnis meiner Bemühungen.
Code: Alles auswählen
--- 20040721/apps/tuxbox/tools/camd/camd.orginal.c Sun Apr 4 22:27:57 2004
+++ 20040721/apps/tuxbox/tools/camd/camd.c Wed Jul 21 16:31:52 2004
@@ -65,11 +65,147 @@
static unsigned char card_country[3];
static unsigned char card_number[10];
-static unsigned char card_version[2];
+static unsigned char card_version[2] = {0xff,0xff};
//end cam-status
static int reset_dmx = 0;
+
+static int last_slot_status = 1;
+static int p_sup = 0;
+static int msg_mask = 0; // test stuff (zum selektiven deaktiveren der Gui-Meldungen)
+
+#define EVT_POPUP 0xA0000003
+#define NEUTRINO_UDS_NAME "/tmp/neutrino.sock"
+
+typedef enum {
+ INITID_CONTROLD,
+ INITID_SECTIONSD,
+ INITID_ZAPIT,
+ INITID_TIMERD,
+ INITID_HTTPD,
+ INITID_NEUTRINO,
+ INITID_GENERIC_INPUT_EVENT_PROVIDER
+} initiators;
+
+typedef struct {
+ unsigned int eventID;
+ unsigned int initiatorID;
+ unsigned int dataSize;
+} eventHead;
+
+
+static void send_gui_message(const char *msg)
+{
+ /*
+ * Message an Gui senden
+ */
+ struct sockaddr_un servaddr;
+ int msgsize;
+ int clilen, sock_fd;
+ int written;
+ eventHead head;
+
+ msgsize = strlen(msg)+1;
+ if(msgsize == 0) return;
+
+ memset(&servaddr, 0, sizeof(struct sockaddr_un));
+ servaddr.sun_family = AF_UNIX;
+ strcpy(servaddr.sun_path, NEUTRINO_UDS_NAME);
+ clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
+
+ if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ printf("[camd]: send_gui_message open socket error");
+ return;
+ }
+
+ if(connect(sock_fd, (struct sockaddr*) &servaddr, clilen) <0 )
+ {
+ printf("[camd]: send_gui_message connect (%s) error", NEUTRINO_UDS_NAME);
+ close(sock_fd);
+ return;
+ }
+
+ head.eventID = EVT_POPUP;
+ head.initiatorID = INITID_HTTPD;
+
+ head.dataSize = msgsize;
+ written = write(sock_fd, &head, sizeof(head));
+ printf ("[camd]: send_gui_message => send 0x%x of 0x%x header bytes\n", written, sizeof(head));
+
+ written = write(sock_fd, msg, msgsize);
+ printf ("[camd]: send_gui_message => send 0x%x of 0x%x msg bytes\n", written, msgsize );
+ close(sock_fd);
+ return;
+}
+
+static void send_gui_status(char status1,char status2)
+{
+ /*
+ * Statusmeldung des Cam's auswerten
+ * wurde getestet mit cam-alpha version 01_02_002E
+ * das zweite byte des Statuscodes ist fuer diese Meldungen irrelevant
+ * eine andere camfirmware kann jedoch eventuell abweichende
+ * Statuscodes ausgeben diese sind mir jedoch unbekannt und muessen ggf
+ * noch ergaenzt werden.
+ */
+ char buffer[256];
+ if (!(status1 & ~msg_mask)) // test stuff (zum selektiven deaktiveren der Gui-Meldungen)
+ return;
+
+ if (status1 == 0xff && status2 & 0x03) {
+ /*
+ * Das Cam sendet beim stecken und ziehen mehr als ein mal
+ * den Kartenstatus fuer die Meldung am Bildschirm reicht es
+ * wenn nur einmal ein Popup aufgeht.
+ */
+ if (last_slot_status == slot2) return;
+ last_slot_status = slot2;
+ }
+
+ switch (status1) {
+ case 0x1d: //ok keine meldung senden
+ break;
+ case 0x50:
+ send_gui_message("Kanal oder Sendezeit nicht freigeschaltet!");
+ break;
+ case 0x80:
+ status1 = 0xff;
+ status2 = 0x02;
+ case 0x84:
+ status1 = 0xff;
+ status2 = 0x08;
+ case 0xff: // pseudostatus wird hoffendlich niemals von Karte gesendet!
+ switch (status2) {
+ case 0x01:
+ send_gui_message("Karte wird geprueft Bitte warten!");
+ break;
+ case 0x02:
+ send_gui_message("Karte wurde entfernt!");
+ break;
+ case 0x04:
+ if (card_version[0] == 0xff && card_version[1] == 0xff && slot2)
+ send_gui_message("Karte defekt oder falsch eingesteckt!");
+ break;
+ case 0x08:
+ if (slot2) {
+ send_gui_message("Der Kanal kann mit dieser Karte nicht entschluesselt werden");
+ break;
+ }
+ status2 = 0x10;
+ case 0x10:
+ send_gui_message("Keine Karte eingesteckt!");
+ break;
+ }
+ break;
+ default:
+ sprintf(buffer,"Unbekannte Kartenantwort:%02x%02x",status1,status2);
+ send_gui_message(buffer);
+ break;
+ }
+}
+
int _writecam(unsigned char command, unsigned char *data, unsigned short length)
{
unsigned short i;
@@ -279,6 +415,10 @@
for (i = 0; i < MAX_SERVICES; i++)
if ((descrambleservice[i].onID == onid) && (descrambleservice[i].sID == sid))
descrambleservice[i].status = (buffer[12] << 8) | buffer[13]; // status for each pid..
+ /*
+ * status des cams an Gui weitergeben
+ */
+ send_gui_status(buffer[12],buffer[13]);
break;
}
@@ -295,10 +435,12 @@
if ((buffer[6] & 0x01) == 0) {
printf("[camd] a card is in slot #1\n");
slot2 = 1;
+ send_gui_status(0xff,0x01);
}
else {
printf("[camd] no card is in slot #1\n");
slot2 = 0;
+ send_gui_status(0xff,0x02);
}
break;
@@ -309,6 +451,7 @@
printf("[camd] card_number: %s\n", card_number);
memcpy(card_version, buffer + 18, 2);
printf("[camd] card_version: %04x\n", *(unsigned short *)card_version);
+ send_gui_status(0xff,0x04);
break;
default:
@@ -405,6 +548,7 @@
int parse_ca_pmt(const unsigned char *buffer, const unsigned int length)
{
unsigned short i, j, k;
+ unsigned short encrypted = 0;
ca_pmt * pmt;
descrambleservice_s service;
@@ -416,13 +560,6 @@
pmt->program_number = *(unsigned short *)&buffer[1];
pmt->program_info_length = *(unsigned short *)&buffer[4] & 0x0fff;
- if ((pmt->program_number & 0xf000) == 0x0000) {
- printf("[camd] program number %04x unsupported due to missing parental control\n",
- pmt->program_number);
- free(pmt);
- return -1;
- }
-
#if 0
printf("ca_pmt_list_management: %02x\n", pmt->ca_pmt_list_management);
printf("program number: %04x\n", pmt->program_number);
@@ -453,6 +590,13 @@
printf("ca_system_id: %04x\n", pmt->program_info->descriptor->ca_system_id);
printf("ca_pid: %04x\n", pmt->program_info->descriptor->ca_pid);
#endif
+ if (pmt->program_info->descriptor->ca_system_id)
+ /*
+ * wenn eine ca_system_id gefunden wird ist der Kanal
+ * in der regel auch verschluesselt
+ */
+ encrypted = 1;
+
for (j = 0; j < caid_count; j++) {
if (caid[j] == pmt->program_info->descriptor->ca_system_id) {
service.caID = pmt->program_info->descriptor->ca_system_id;
@@ -501,6 +645,13 @@
printf("ca_system_id: %04x\n", pmt->es_info->program_info->descriptor->ca_system_id);
printf("ca_pid: %04x\n", pmt->es_info->program_info->descriptor->ca_pid);
#endif
+ if (pmt->es_info->program_info->descriptor->ca_system_id)
+ /*
+ * wenn eine ca_system_id gefunden wird ist der Kanal
+ * in der regel auch verschluesselt
+ */
+ encrypted = 1;
+
for (k = 0; k < caid_count; k++) {
if (caid[k] == pmt->es_info->program_info->descriptor->ca_system_id) {
service.caID = pmt->es_info->program_info->descriptor->ca_system_id;
@@ -525,10 +676,33 @@
if ((service.numpids != 0) && (service.caID != 0)) {
service.onID = 0x0001;
+ /*
+ * an dieser stelle steht fest ob der Kanal verschluesselt
+ * ist und auch vom cam entschluesselt werden kann
+ */
+ if (!p_sup) {
+ if ((service.sID & 0xf000) == 0x0000) {
+ /*
+ * jetzt sind nur noch verschluesselte premiere kanaele uebrig
+ */
+ send_gui_message("program unsupported due to missing parental control");
+ printf("[camd] program number %04x unsupported due to missing parental control\n",
+ service.sID);
+ return -1;
+ }
+ }
add_descrambleservice(&service);
return 0;
}
+ if (encrypted)
+ /*
+ * hier wird fuer alle verschluesselten kanaele die nicht vom
+ * cam supported werden die Fehlermeldung ausgegeben
+ * Die erkennung klappt aber leider noch nicht bei allen verschluesselungen
+ */
+ send_gui_status(0xff,0x08);
+
return -1;
}
@@ -675,7 +849,9 @@
struct pollfd pfd[3];
ssize_t len;
struct dmx_sct_filter_params dsfp;
- int i;
+ int i = 0;
+ char cmd;
+ char *arg = NULL;
switch (fork()) {
case -1:
@@ -702,6 +878,39 @@
return 1;
}
+/*
+ * kleine routine zum einschalten des premiere supports
+ * ist nur zum testen gedacht, bei Cam's die in oeffendlich
+ * angebotenen Images verwendet werden muss das natuerlich raus
+ */
+ while (++i < argc)
+ {
+ if (argv[i][0] == '-')
+ {
+ cmd = argv[i][1];
+ }
+ else
+ continue;
+
+ if (i + 1 < argc)
+ {
+ if (argv[i+1][0] != '-')
+ {
+ i++;
+ arg = (char*)argv[i];
+ }
+ else
+ arg = NULL;
+ }
+
+ switch (cmd)
+ {
+ case 'p':
+ p_sup = 1;
+ break;
+ }
+ }
+
/* software reset */
reset();
Falls es einem der Developer gefällt kann er es vielleicht sogar ins CVS übernehmen.
Meine dann im Code überflüssigen Kommentare bitte entfernen.