/* This was: * cct.c: Routines to communicate with VTX-decoder SAA 5246 & compatibles (eg. 5243) via * I²C-routines * * Copyright (c) 1994-96 Martin Buck * Read COPYING for more information Now it is completely rewritten to contact the qqs_daemon! * */ #include #include #include #include #include #include "cct.h" #include #include #include #include #include #include #define CLN_PORT 5400 #define NBUF 8 /* well, that's fake of course */ #define ENTER(a) fprintf (stderr, "entering %s\n", a); #define EXIT(a) fprintf (stderr, "exit %s\n", a); char *cct_device = "/dev/vtx"; static int vtxfd = -1; /* now this is the socket */ char question[16]; char answer[1024]; struct { int page, hour, min, mask; } request[8]; /* Wait for an answer from the daemon return CCTOK if "OK" CCTERR otherwise */ int cct_ok(void) { ENTER("cct_ok"); read (vtxfd, answer, 1024); EXIT("cct_ok"); return (strncmp(answer, "OK", 2) ? CCTERR : CCTOK); } int cct_tune(int freq) { ENTER("cct_tune"); sprintf (question, "T %6d\n", freq); write (vtxfd, question, 10); return (cct_ok()); EXIT("cct_tune"); } /* Open socket to daemon * Return CCTOK if success, CCTEOPEN if device isn't ready, CCTERR if I/O-error occured, * CCTEVERSION if driver-version isn't compatible */ int cct_open(int major, int minor, vtx_info_t *prg_info) { struct sockaddr_in server; struct hostent *hp, *gethostbyname(); ENTER("cct_open"); vtxfd = socket (AF_INET, SOCK_STREAM, 0); if (vtxfd<0) { perror("opening stream socket"); return CCTEOPEN; } server.sin_family = AF_INET; hp = gethostbyname("localhost"); if (hp == 0) { fprintf (stderr, "%s: unknown host, enter valid host name\n", "localhost"); return CCTEOPEN; } memcpy ((char *)&server.sin_addr, (char *)hp -> h_addr, hp -> h_length); server.sin_port = CLN_PORT; if (connect(vtxfd, (struct sockaddr *) &server, sizeof server) < 0) { perror ("connecting stream socket"); return CCTEOPEN; } prg_info -> version_major = 0; prg_info -> version_minor = 0; prg_info -> numpages = NBUF; prg_info -> cct_type = 5; EXIT("cct_open"); return CCTOK; } /* Turn off */ void cct_close(void) { close(vtxfd); } /* Clear page-buffer pgbuf in SAA 5246 & wait. * Return CCTOK if success, CCTEINVAL if pgbuf is out of range, CCTERR if I/O-error occured */ int cct_clearpgbuf(int pgbuf) { ENTER("cct_clearpgbuf"); if (pgbuf >= NBUF) return CCTEINVAL; request[pgbuf].page = 0; request[pgbuf].hour = 0; request[pgbuf].min = 0; request[pgbuf].mask = 0; EXIT("cct_clearpgbuf"); return (CCTOK); } /* Check if already found a page in pgbuf. This only checks if the * beginning of a page was found, NOT the whole page! * Return CCTOK if page was found, CCTNOTFOUND if no page was found, CCTEINVAL if pgbuf is out */ int cct_checkpage(int pgbuf) { /* vtx_pagereq_t pagereq; vtx_pageinfo_t pageinfo; */ if (vtxfd == -1) return CCTENOTOPEN; if (pgbuf >= NBUF) return CCTEINVAL; sprintf (question, "Q %3x %2x %2x %2x\n", request[pgbuf].page, request[pgbuf].hour, request[pgbuf].min, request[pgbuf].mask); fprintf (stderr, "cct_checkpage: %s", question); write (vtxfd, question, 15); read (vtxfd, answer, 1024); fprintf (stderr, "cct_checkpage: -> %c%c\n", answer[0], answer[1]); return (answer[0] == 'O' ? CCTOK : CCTNOTFOUND); } /* Stop data acquisition unit for pgbuf. * Return CCTOK if success, CCTEINVAL if pgbuf is out of range, CCTERR if I/O-error occured */ int cct_stop_dau(int pgbuf) { /* vtx_pagereq_t pagereq; ENTER("cct_stop_dau"); if (vtxfd == -1) return CCTENOTOPEN; if (pgbuf >= NBUF) return CCTEINVAL; sprintf (question, "R\n", pgbuf); write (vtxfd, question, 3); EXIT("cct_stop_dau"); return (cct_ok()); */ return CCTOK; } /* Reset bits in pgbuf used to check if a page was already found * Return CCTOK if success, CCTEINVAL if pgbuf is out of range, CCTERR if I/O-error occured */ int cct_reset_pgfound(int pgbuf) { /* vtx_pagereq_t pagereq; if (vtxfd == -1) return CCTENOTOPEN; if (pgbuf >= NBUF) return CCTEINVAL; sprintf (question, "C %1d\n", pgbuf); return (cct_ok()); */ return CCTOK; } /* Search for page page/hour/minute (hexadecimal !!!), only regard digits with corresponding bits * in pagemask set (constants defined in ), store page in page-buffer pgbuf * Return CCTOK if success, CCTEINVAL if page, hour, minute or pgbuf is out of range, CCTERR if I/O-error occured */ int cct_searchpage(int page, int hour, int minute, int pagemask, int pgbuf) { vtx_pagereq_t pagereq; if (vtxfd == -1) return CCTENOTOPEN; if (pgbuf >= NBUF) return CCTEINVAL; request[pgbuf].page = page; request[pgbuf].hour = hour; request[pgbuf].min = minute; request[pgbuf].mask = pagemask; return CCTOK; } /* Get page from page-buffer pgbuf of SAA 5246 (first char x1/y1, last char x2/y2), store it in * buffer (= ptr to array of byte_t's) * Return CCTOK if success, CCTEINVAL if corner-coordinates or pgbuf is invalid, CCTERR if * I/O-error occured */ int cct_getpage(int pgbuf, int x1, int y1, int x2, int y2, byte_t *buffer, vtx_pageinfo_t *info) { int nread, first, last; struct { char cc[2]; short page; char hour, minute, cntrh, cntrl; } answer; struct { int pagenum, hour, minute, charset; short others; } * myinfo = info; if (vtxfd == -1) { fprintf (stderr, "not_open\n"); return CCTENOTOPEN; } if (pgbuf >= NBUF) { fprintf (stderr, "inval\n"); return CCTEINVAL; } sprintf (question, "Q %3x %2x %2x %2x\n", request[pgbuf].page, request[pgbuf].hour, request[pgbuf].min, request[pgbuf].mask); fprintf (stderr, "Question is %s", question); write (vtxfd, question, 15); read (vtxfd, &answer, 1024); if (answer.cc[0] != 'O') { fprintf (stderr, "NOT OK\n"); return CCTNOTFOUND; } if (myinfo) { myinfo -> pagenum = answer.page; myinfo -> hour = answer.hour; myinfo -> minute = answer.minute; myinfo -> charset = answer.cntrh >> 4; myinfo -> others = (answer.cntrl >> 4 || answer.cntrh << 4) & 0xff; } first = y1 * 40 + x1; last = y2 * 40 + x2; sprintf (question, "G %4d %4d\n", first, last); write (vtxfd, question, 13); nread = read (vtxfd, buffer, last-first+1); return (nread == last - first+1 ? CCTOK : CCTERR); } /* Display page in buffer (first char x1/y1, last char x2/y2) on TV-Screen. * Return CCTOK if success, CCTEINVAL if corner-coordinates or are invalid, CCTERR if * I/O-error occured */ int cct_putpage(int x1, int y1, int x2, int y2, const byte_t *buffer, const vtx_pageinfo_t *info) { return CCTOK; } /* Set mode of video-output of SAA5246 (for displaying pages on TV-screen). * Return CCTOK if success of CCTERR if I/O-error occured. */ int cct_set_display(vtxdisp_t disp) { return CCTOK; } /* Clear the page-cache on cards that have one. * Return CCTOK if success (or if interface has noch cache) or CCTERR if I/O-error occured. */ int cct_clear_cache(void) { if (vtxfd == -1) return CCTENOTOPEN; write (vtxfd, "P\n", 2); return (cct_ok()); } /* Turn on/off virtual mode. Most interfaces can't display a page on TV if virtual mode is on! * Return CCTOK if success or CCTERR if I/O-error occured. */ int cct_set_virtual(int virtual) { return (CCTOK); }