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.1 2006/05/07 20:55:00 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 <errno.h>
00034 
00035 #include <libzvbi.h>
00036 
00037 static vbi_capture *            cap;
00038 static vbi_decoder *            dec;
00039 static vbi_bool                 quit;
00040 
00041 static unsigned int             services;
00042 
00043 static void
00044 handler                         (vbi_event *            ev,
00045                                  void *                 user_data)
00046 {
00047         const char *event_name;
00048         const char *network_name;
00049         const char *call_sign;
00050 
00051         user_data = user_data; /* unused */
00052 
00053         /* VBI_EVENT_NETWORK_ID is always sent when the decoder
00054            receives a CNI. VBI_EVENT_NETWORK only if it can
00055            determine a network name. */
00056 
00057         switch (ev->type) {
00058         case VBI_EVENT_NETWORK:
00059                 event_name = "VBI_EVENT_NETWORK";
00060                 quit = TRUE;
00061                 break;
00062 
00063         case VBI_EVENT_NETWORK_ID:
00064                 event_name = "VBI_EVENT_NETWORK_ID";
00065                 break;
00066 
00067         default:
00068                 assert (0);
00069         }
00070 
00071         /* Note this is an ISO-8859-1 string (yeah it's a pretty old
00072            API). Use iconv() to convert to nl_langinfo(CODESET). */
00073         network_name = "unknown";
00074         if (0 != ev->ev.network.name[0])
00075                 network_name = ev->ev.network.name;
00076 
00077         /* ASCII. */
00078         call_sign = "unknown";
00079         if (0 != ev->ev.network.call[0])
00080                 call_sign = ev->ev.network.call;
00081 
00082         printf ("%s: receiving: \"%s\" call sign: \"%s\" "
00083                 "CNI VPS: 0x%x 8/30-1: 0x%x 8/30-2: 0x%x\n",
00084                 event_name,
00085                 network_name,
00086                 call_sign,
00087                 ev->ev.network.cni_vps,
00088                 ev->ev.network.cni_8301,
00089                 ev->ev.network.cni_8302);
00090 }
00091 
00092 static void
00093 mainloop                        (void)
00094 {
00095         struct timeval timeout;
00096         vbi_capture_buffer *sliced_buffer;
00097         unsigned int n_frames;
00098 
00099         /* Don't wait more than two seconds for the driver
00100            to return data. */
00101         timeout.tv_sec = 2;
00102         timeout.tv_usec = 0;
00103 
00104         /* Should receive a CNI within two seconds,
00105            call sign within ten seconds(?). */
00106         if (services & VBI_SLICED_CAPTION_525)
00107                 n_frames = 11 * 30;
00108         else
00109                 n_frames = 3 * 25;
00110 
00111         for (; n_frames > 0; --n_frames) {
00112                 unsigned int n_lines;
00113                 int r;
00114 
00115                 r = vbi_capture_pull (cap,
00116                                       /* raw_buffer */ NULL,
00117                                       &sliced_buffer,
00118                                       &timeout);
00119                 switch (r) {
00120                 case -1:
00121                         fprintf (stderr, "VBI read error %d (%s)\n",
00122                                  errno, strerror (errno));
00123                         /* Could be ignored, esp. EIO with some drivers. */
00124                         exit(EXIT_FAILURE);
00125 
00126                 case 0: 
00127                         fprintf (stderr, "VBI read timeout\n");
00128                         exit(EXIT_FAILURE);
00129 
00130                 case 1: /* success */
00131                         break;
00132 
00133                 default:
00134                         assert (0);
00135                 }
00136 
00137                 n_lines = sliced_buffer->size / sizeof (vbi_sliced);
00138 
00139                 vbi_decode (dec,
00140                             (vbi_sliced *) sliced_buffer->data,
00141                             n_lines,
00142                             sliced_buffer->timestamp);
00143 
00144                 if (quit)
00145                         return;
00146         }
00147 
00148         printf ("No network ID received or network unknown.\n");
00149 }
00150 
00151 int
00152 main                            (void)
00153 {
00154         char *errstr;
00155         vbi_bool success;
00156 
00157         services = (VBI_SLICED_TELETEXT_B |
00158                     VBI_SLICED_VPS |
00159                     VBI_SLICED_CAPTION_525);
00160 
00161         cap = vbi_capture_v4l2_new ("/dev/vbi",
00162                                     /* buffers */ 5,
00163                                     &services,
00164                                     /* strict */ 0,
00165                                     &errstr,
00166                                     /* verbose */ FALSE);
00167         if (NULL == cap) {
00168                 fprintf (stderr,
00169                          "Cannot capture VBI data with V4L2 interface:\n"
00170                          "%s\n",
00171                          errstr);
00172 
00173                 free (errstr);
00174                 errstr = NULL;
00175 
00176                 exit (EXIT_FAILURE);
00177         }
00178 
00179         dec = vbi_decoder_new ();
00180         assert (NULL != dec);
00181 
00182         success = vbi_event_handler_add (dec,
00183                                          (VBI_EVENT_NETWORK |
00184                                           VBI_EVENT_NETWORK_ID),
00185                                          handler,
00186                                          /* user_data */ NULL);
00187         assert (success);
00188 
00189         mainloop ();
00190 
00191         vbi_decoder_delete (dec);
00192         dec = NULL;
00193 
00194         vbi_capture_delete (cap);
00195         cap = NULL;
00196 
00197         exit (EXIT_SUCCESS);
00198 }

Generated on Tue Mar 6 07:33:18 2007 for ZVBI Library by  doxygen 1.4.7