summaryrefslogtreecommitdiff
path: root/examples/network.c (plain)
blob: e8546c1754d5cc8bf326b3b8463e6d5e15b84be7
1/*
2 * libzvbi network identification example
3 *
4 * Copyright (C) 2006 Michael H. Schimek
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/* $Id: network.c,v 1.5 2008/02/19 00:51:51 mschimek Exp $ */
29
30/* This example shows how to identify a network from data transmitted
31 in XDS packets, Teletext packet 8/30 format 1 and 2, and VPS packets.
32
33 gcc -o network network.c `pkg-config zvbi-0.2 --cflags --libs` */
34
35#undef NDEBUG
36#include <assert.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <locale.h>
41#include <errno.h>
42
43#include <libzvbi.h>
44
45static vbi_capture * cap;
46static vbi_decoder * dec;
47static vbi_bool quit;
48
49static unsigned int services;
50
51static void
52handler (vbi_event * ev,
53 void * user_data)
54{
55 const char *event_name;
56 const char *network_name;
57 const char *call_sign;
58 char *locale_network_name;
59
60 user_data = user_data; /* unused */
61
62 /* VBI_EVENT_NETWORK_ID is always sent when the decoder
63 receives a CNI. VBI_EVENT_NETWORK only if it can
64 determine a network name. */
65
66 switch (ev->type) {
67 case VBI_EVENT_NETWORK:
68 event_name = "VBI_EVENT_NETWORK";
69 quit = TRUE;
70 break;
71
72 case VBI_EVENT_NETWORK_ID:
73 event_name = "VBI_EVENT_NETWORK_ID";
74 break;
75
76 default:
77 assert (0);
78 }
79
80 network_name = "unknown";
81 if (0 != ev->ev.network.name[0])
82 network_name = ev->ev.network.name;
83
84 /* The network name is an ISO-8859-1 string (the API is
85 quite old...) so we convert it to locale encoding,
86 nowadays usually UTF-8. */
87 locale_network_name = vbi_strndup_iconv (vbi_locale_codeset (),
88 "ISO-8859-1",
89 network_name,
90 strlen (network_name),
91 /* repl_char */ '?');
92
93 /* ASCII. */
94 call_sign = "unknown";
95 if (0 != ev->ev.network.call[0])
96 call_sign = ev->ev.network.call;
97
98 printf ("%s: receiving: \"%s\" call sign: \"%s\" "
99 "CNI VPS: 0x%x 8/30-1: 0x%x 8/30-2: 0x%x\n",
100 event_name,
101 (NULL == locale_network_name) ?
102 "iconv-error" : locale_network_name,
103 call_sign,
104 ev->ev.network.cni_vps,
105 ev->ev.network.cni_8301,
106 ev->ev.network.cni_8302);
107
108 free (locale_network_name);
109}
110
111static void
112mainloop (void)
113{
114 struct timeval timeout;
115 vbi_capture_buffer *sliced_buffer;
116 unsigned int n_frames;
117
118 /* Don't wait more than two seconds for the driver
119 to return data. */
120 timeout.tv_sec = 2;
121 timeout.tv_usec = 0;
122
123 /* Should receive a CNI within two seconds,
124 call sign within ten seconds(?). */
125 if (services & VBI_SLICED_CAPTION_525)
126 n_frames = 11 * 30;
127 else
128 n_frames = 3 * 25;
129
130 for (; n_frames > 0; --n_frames) {
131 unsigned int n_lines;
132 int r;
133
134 r = vbi_capture_pull (cap,
135 /* raw_buffer */ NULL,
136 &sliced_buffer,
137 &timeout);
138 switch (r) {
139 case -1:
140 fprintf (stderr, "VBI read error %d (%s)\n",
141 errno, strerror (errno));
142 /* Could be ignored, esp. EIO with some drivers. */
143 exit(EXIT_FAILURE);
144
145 case 0:
146 fprintf (stderr, "VBI read timeout\n");
147 exit(EXIT_FAILURE);
148
149 case 1: /* success */
150 break;
151
152 default:
153 assert (0);
154 }
155
156 n_lines = sliced_buffer->size / sizeof (vbi_sliced);
157
158 vbi_decode (dec,
159 (vbi_sliced *) sliced_buffer->data,
160 n_lines,
161 sliced_buffer->timestamp);
162
163 if (quit)
164 return;
165 }
166
167 printf ("No network ID received or network unknown.\n");
168}
169
170int
171main (void)
172{
173 char *errstr;
174 vbi_bool success;
175
176 setlocale (LC_ALL, "");
177
178 services = (VBI_SLICED_TELETEXT_B |
179 VBI_SLICED_VPS |
180 VBI_SLICED_CAPTION_525);
181
182 cap = vbi_capture_v4l2_new ("/dev/vbi",
183 /* buffers */ 5,
184 &services,
185 /* strict */ 0,
186 &errstr,
187 /* verbose */ FALSE);
188 if (NULL == cap) {
189 fprintf (stderr,
190 "Cannot capture VBI data with V4L2 interface:\n"
191 "%s\n",
192 errstr);
193
194 free (errstr);
195 errstr = NULL;
196
197 exit (EXIT_FAILURE);
198 }
199
200 dec = vbi_decoder_new ();
201 assert (NULL != dec);
202
203 success = vbi_event_handler_add (dec,
204 (VBI_EVENT_NETWORK |
205 VBI_EVENT_NETWORK_ID),
206 handler,
207 /* user_data */ NULL);
208 assert (success);
209
210 mainloop ();
211
212 vbi_decoder_delete (dec);
213 dec = NULL;
214
215 vbi_capture_delete (cap);
216 cap = NULL;
217
218 exit (EXIT_SUCCESS);
219}
220