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 }