examples/network.c

Network identification example.

00001 /*
00002  *  libzvbi network identification example.
00003  *
00004  *  Copyright (C) 2006 Michael H. Schimek
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 /* $Id: network.c,v 1.2 2006/10/27 04:52:08 mschimek Exp $ */
00022 
00023 /* This example shows how to identify a network from data transmitted
00024    in XDS packets, Teletext packet 8/30 format 1 and 2, and VPS packets.
00025 
00026    gcc -o network network.c `pkg-config zvbi-0.2 --cflags --libs` */
00027 
00028 #undef NDEBUG
00029 #include <assert.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <locale.h>
00034 #include <errno.h>
00035 
00036 #include <libzvbi.h>
00037 
00038 static vbi_capture *            cap;
00039 static vbi_decoder *            dec;
00040 static vbi_bool                 quit;
00041 
00042 static unsigned int             services;
00043 
00044 static void
00045 handler                         (vbi_event *            ev,
00046                                  void *                 user_data)
00047 {
00048         const char *event_name;
00049         const char *network_name;
00050         const char *call_sign;
00051         char *locale_network_name;
00052 
00053         user_data = user_data; /* unused */
00054 
00055         /* VBI_EVENT_NETWORK_ID is always sent when the decoder
00056            receives a CNI. VBI_EVENT_NETWORK only if it can
00057            determine a network name. */
00058 
00059         switch (ev->type) {
00060         case VBI_EVENT_NETWORK:
00061                 event_name = "VBI_EVENT_NETWORK";
00062                 quit = TRUE;
00063                 break;
00064 
00065         case VBI_EVENT_NETWORK_ID:
00066                 event_name = "VBI_EVENT_NETWORK_ID";
00067                 break;
00068 
00069         default:
00070                 assert (0);
00071         }
00072 
00073         network_name = "unknown";
00074         if (0 != ev->ev.network.name[0])
00075                 network_name = ev->ev.network.name;
00076 
00077         /* The network name is an ISO-8859-1 string (the API is
00078            quite old...) so we convert it to locale encoding,
00079            nowadays usually UTF-8. */
00080         locale_network_name = vbi_strndup_iconv (vbi_locale_codeset (),
00081                                                  "ISO-8859-1",
00082                                                  network_name,
00083                                                  strlen (network_name),
00084                                                  /* repl_char */ '?');
00085 
00086         /* ASCII. */
00087         call_sign = "unknown";
00088         if (0 != ev->ev.network.call[0])
00089                 call_sign = ev->ev.network.call;
00090 
00091         printf ("%s: receiving: \"%s\" call sign: \"%s\" "
00092                 "CNI VPS: 0x%x 8/30-1: 0x%x 8/30-2: 0x%x\n",
00093                 event_name,
00094                 (NULL == locale_network_name) ?
00095                 "iconv-error" : locale_network_name,
00096                 call_sign,
00097                 ev->ev.network.cni_vps,
00098                 ev->ev.network.cni_8301,
00099                 ev->ev.network.cni_8302);
00100 
00101         free (locale_network_name);
00102 }
00103 
00104 static void
00105 mainloop                        (void)
00106 {
00107         struct timeval timeout;
00108         vbi_capture_buffer *sliced_buffer;
00109         unsigned int n_frames;
00110 
00111         /* Don't wait more than two seconds for the driver
00112            to return data. */
00113         timeout.tv_sec = 2;
00114         timeout.tv_usec = 0;
00115 
00116         /* Should receive a CNI within two seconds,
00117            call sign within ten seconds(?). */
00118         if (services & VBI_SLICED_CAPTION_525)
00119                 n_frames = 11 * 30;
00120         else
00121                 n_frames = 3 * 25;
00122 
00123         for (; n_frames > 0; --n_frames) {
00124                 unsigned int n_lines;
00125                 int r;
00126 
00127                 r = vbi_capture_pull (cap,
00128                                       /* raw_buffer */ NULL,
00129                                       &sliced_buffer,
00130                                       &timeout);
00131                 switch (r) {
00132                 case -1:
00133                         fprintf (stderr, "VBI read error %d (%s)\n",
00134                                  errno, strerror (errno));
00135                         /* Could be ignored, esp. EIO with some drivers. */
00136                         exit(EXIT_FAILURE);
00137 
00138                 case 0: 
00139                         fprintf (stderr, "VBI read timeout\n");
00140                         exit(EXIT_FAILURE);
00141 
00142                 case 1: /* success */
00143                         break;
00144 
00145                 default:
00146                         assert (0);
00147                 }
00148 
00149                 n_lines = sliced_buffer->size / sizeof (vbi_sliced);
00150 
00151                 vbi_decode (dec,
00152                             (vbi_sliced *) sliced_buffer->data,
00153                             n_lines,
00154                             sliced_buffer->timestamp);
00155 
00156                 if (quit)
00157                         return;
00158         }
00159 
00160         printf ("No network ID received or network unknown.\n");
00161 }
00162 
00163 int
00164 main                            (void)
00165 {
00166         char *errstr;
00167         vbi_bool success;
00168 
00169         setlocale (LC_ALL, "");
00170 
00171         services = (VBI_SLICED_TELETEXT_B |
00172                     VBI_SLICED_VPS |
00173                     VBI_SLICED_CAPTION_525);
00174 
00175         cap = vbi_capture_v4l2_new ("/dev/vbi",
00176                                     /* buffers */ 5,
00177                                     &services,
00178                                     /* strict */ 0,
00179                                     &errstr,
00180                                     /* verbose */ FALSE);
00181         if (NULL == cap) {
00182                 fprintf (stderr,
00183                          "Cannot capture VBI data with V4L2 interface:\n"
00184                          "%s\n",
00185                          errstr);
00186 
00187                 free (errstr);
00188                 errstr = NULL;
00189 
00190                 exit (EXIT_FAILURE);
00191         }
00192 
00193         dec = vbi_decoder_new ();
00194         assert (NULL != dec);
00195 
00196         success = vbi_event_handler_add (dec,
00197                                          (VBI_EVENT_NETWORK |
00198                                           VBI_EVENT_NETWORK_ID),
00199                                          handler,
00200                                          /* user_data */ NULL);
00201         assert (success);
00202 
00203         mainloop ();
00204 
00205         vbi_decoder_delete (dec);
00206         dec = NULL;
00207 
00208         vbi_capture_delete (cap);
00209         cap = NULL;
00210 
00211         exit (EXIT_SUCCESS);
00212 }

Generated on Thu Aug 23 06:09:28 2007 for ZVBI Library by  doxygen 1.5.3