examples/network.c

Network identification example.

00001 /*
00002  *  libzvbi network identification example
00003  *
00004  *  Copyright (C) 2006 Michael H. Schimek
00005  *
00006  *  Redistribution and use in source and binary forms, with or without
00007  *  modification, are permitted provided that the following conditions
00008  *  are met:
00009  *  1. Redistributions of source code must retain the above copyright
00010  *     notice, this list of conditions and the following disclaimer.
00011  *  2. Redistributions in binary form must reproduce the above copyright
00012  *     notice, this list of conditions and the following disclaimer in
00013  *     the documentation and/or other materials provided with the
00014  *     distribution.
00015  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00016  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00017  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00018  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00019  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00021  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00022  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00023  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00028 /* $Id: network.c,v 1.5 2008/02/19 00:51:51 mschimek Exp $ */
00029 
00030 /* This example shows how to identify a network from data transmitted
00031    in XDS packets, Teletext packet 8/30 format 1 and 2, and VPS packets.
00032 
00033    gcc -o network network.c `pkg-config zvbi-0.2 --cflags --libs` */
00034 
00035 #undef NDEBUG
00036 #include <assert.h>
00037 #include <stdio.h>
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <locale.h>
00041 #include <errno.h>
00042 
00043 #include <libzvbi.h>
00044 
00045 static vbi_capture *            cap;
00046 static vbi_decoder *            dec;
00047 static vbi_bool                 quit;
00048 
00049 static unsigned int             services;
00050 
00051 static void
00052 handler                         (vbi_event *            ev,
00053                                  void *                 user_data)
00054 {
00055         const char *event_name;
00056         const char *network_name;
00057         const char *call_sign;
00058         char *locale_network_name;
00059 
00060         user_data = user_data; /* unused */
00061 
00062         /* VBI_EVENT_NETWORK_ID is always sent when the decoder
00063            receives a CNI. VBI_EVENT_NETWORK only if it can
00064            determine a network name. */
00065 
00066         switch (ev->type) {
00067         case VBI_EVENT_NETWORK:
00068                 event_name = "VBI_EVENT_NETWORK";
00069                 quit = TRUE;
00070                 break;
00071 
00072         case VBI_EVENT_NETWORK_ID:
00073                 event_name = "VBI_EVENT_NETWORK_ID";
00074                 break;
00075 
00076         default:
00077                 assert (0);
00078         }
00079 
00080         network_name = "unknown";
00081         if (0 != ev->ev.network.name[0])
00082                 network_name = ev->ev.network.name;
00083 
00084         /* The network name is an ISO-8859-1 string (the API is
00085            quite old...) so we convert it to locale encoding,
00086            nowadays usually UTF-8. */
00087         locale_network_name = vbi_strndup_iconv (vbi_locale_codeset (),
00088                                                  "ISO-8859-1",
00089                                                  network_name,
00090                                                  strlen (network_name),
00091                                                  /* repl_char */ '?');
00092 
00093         /* ASCII. */
00094         call_sign = "unknown";
00095         if (0 != ev->ev.network.call[0])
00096                 call_sign = ev->ev.network.call;
00097 
00098         printf ("%s: receiving: \"%s\" call sign: \"%s\" "
00099                 "CNI VPS: 0x%x 8/30-1: 0x%x 8/30-2: 0x%x\n",
00100                 event_name,
00101                 (NULL == locale_network_name) ?
00102                 "iconv-error" : locale_network_name,
00103                 call_sign,
00104                 ev->ev.network.cni_vps,
00105                 ev->ev.network.cni_8301,
00106                 ev->ev.network.cni_8302);
00107 
00108         free (locale_network_name);
00109 }
00110 
00111 static void
00112 mainloop                        (void)
00113 {
00114         struct timeval timeout;
00115         vbi_capture_buffer *sliced_buffer;
00116         unsigned int n_frames;
00117 
00118         /* Don't wait more than two seconds for the driver
00119            to return data. */
00120         timeout.tv_sec = 2;
00121         timeout.tv_usec = 0;
00122 
00123         /* Should receive a CNI within two seconds,
00124            call sign within ten seconds(?). */
00125         if (services & VBI_SLICED_CAPTION_525)
00126                 n_frames = 11 * 30;
00127         else
00128                 n_frames = 3 * 25;
00129 
00130         for (; n_frames > 0; --n_frames) {
00131                 unsigned int n_lines;
00132                 int r;
00133 
00134                 r = vbi_capture_pull (cap,
00135                                       /* raw_buffer */ NULL,
00136                                       &sliced_buffer,
00137                                       &timeout);
00138                 switch (r) {
00139                 case -1:
00140                         fprintf (stderr, "VBI read error %d (%s)\n",
00141                                  errno, strerror (errno));
00142                         /* Could be ignored, esp. EIO with some drivers. */
00143                         exit(EXIT_FAILURE);
00144 
00145                 case 0: 
00146                         fprintf (stderr, "VBI read timeout\n");
00147                         exit(EXIT_FAILURE);
00148 
00149                 case 1: /* success */
00150                         break;
00151 
00152                 default:
00153                         assert (0);
00154                 }
00155 
00156                 n_lines = sliced_buffer->size / sizeof (vbi_sliced);
00157 
00158                 vbi_decode (dec,
00159                             (vbi_sliced *) sliced_buffer->data,
00160                             n_lines,
00161                             sliced_buffer->timestamp);
00162 
00163                 if (quit)
00164                         return;
00165         }
00166 
00167         printf ("No network ID received or network unknown.\n");
00168 }
00169 
00170 int
00171 main                            (void)
00172 {
00173         char *errstr;
00174         vbi_bool success;
00175 
00176         setlocale (LC_ALL, "");
00177 
00178         services = (VBI_SLICED_TELETEXT_B |
00179                     VBI_SLICED_VPS |
00180                     VBI_SLICED_CAPTION_525);
00181 
00182         cap = vbi_capture_v4l2_new ("/dev/vbi",
00183                                     /* buffers */ 5,
00184                                     &services,
00185                                     /* strict */ 0,
00186                                     &errstr,
00187                                     /* verbose */ FALSE);
00188         if (NULL == cap) {
00189                 fprintf (stderr,
00190                          "Cannot capture VBI data with V4L2 interface:\n"
00191                          "%s\n",
00192                          errstr);
00193 
00194                 free (errstr);
00195                 errstr = NULL;
00196 
00197                 exit (EXIT_FAILURE);
00198         }
00199 
00200         dec = vbi_decoder_new ();
00201         assert (NULL != dec);
00202 
00203         success = vbi_event_handler_add (dec,
00204                                          (VBI_EVENT_NETWORK |
00205                                           VBI_EVENT_NETWORK_ID),
00206                                          handler,
00207                                          /* user_data */ NULL);
00208         assert (success);
00209 
00210         mainloop ();
00211 
00212         vbi_decoder_delete (dec);
00213         dec = NULL;
00214 
00215         vbi_capture_delete (cap);
00216         cap = NULL;
00217 
00218         exit (EXIT_SUCCESS);
00219 }

Generated on Mon Dec 6 21:33:13 2010 for ZVBI Library by  doxygen 1.4.7