examples/network.c

Network identification example.

/*
* libzvbi network identification example
*
* Copyright (C) 2006 Michael H. Schimek
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id: network.c,v 1.8 2013-08-28 14:45:53 mschimek Exp $ */
/* This example shows how to identify a network from data transmitted
in XDS packets, Teletext packet 8/30 format 1 and 2, and VPS packets.
gcc -o network network.c `pkg-config zvbi-0.2 --cflags --libs` */
#undef NDEBUG
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <errno.h>
#include <libzvbi.h>
static vbi_capture * cap;
static vbi_decoder * dec;
static vbi_bool quit;
static unsigned int services;
static void
handler (vbi_event * ev,
void * user_data)
{
const char *event_name;
const char *network_name;
const char *call_sign;
char *locale_network_name;
user_data = user_data; /* unused */
/* VBI_EVENT_NETWORK_ID is always sent when the decoder
receives a CNI. VBI_EVENT_NETWORK only if it can
determine a network name. */
switch (ev->type) {
case VBI_EVENT_NETWORK:
event_name = "VBI_EVENT_NETWORK";
quit = TRUE;
break;
case VBI_EVENT_NETWORK_ID:
event_name = "VBI_EVENT_NETWORK_ID";
break;
default:
assert (0);
}
network_name = "unknown";
if (0 != ev->ev.network.name[0])
network_name = (const char *) ev->ev.network.name;
/* The network name is an ISO-8859-1 string (the API is
quite old...) so we convert it to locale encoding,
nowadays usually UTF-8. */
locale_network_name = vbi_strndup_iconv (vbi_locale_codeset (),
"ISO-8859-1",
network_name,
strlen (network_name),
/* repl_char */ '?');
/* ASCII. */
call_sign = "unknown";
if (0 != ev->ev.network.call[0])
call_sign = (const char *) ev->ev.network.call;
printf ("%s: receiving: \"%s\" call sign: \"%s\" "
"CNI VPS: 0x%x 8/30/1: 0x%x 8/30/2: 0x%x\n",
event_name,
(NULL == locale_network_name) ?
"iconv-error" : locale_network_name,
call_sign,
ev->ev.network.cni_vps,
ev->ev.network.cni_8301,
ev->ev.network.cni_8302);
free (locale_network_name);
}
static void
mainloop (void)
{
struct timeval timeout;
vbi_capture_buffer *sliced_buffer;
unsigned int n_frames;
/* Don't wait more than two seconds for the driver
to return data. */
timeout.tv_sec = 2;
timeout.tv_usec = 0;
/* Should receive a CNI within two seconds,
call sign within ten seconds(?). */
if (services & VBI_SLICED_CAPTION_525)
n_frames = 11 * 30;
else
n_frames = 3 * 25;
for (; n_frames > 0; --n_frames) {
unsigned int n_lines;
int r;
r = vbi_capture_pull (cap,
/* raw_buffer */ NULL,
&sliced_buffer,
&timeout);
switch (r) {
case -1:
fprintf (stderr, "VBI read error %d (%s)\n",
errno, strerror (errno));
/* Could be ignored, esp. EIO with some drivers. */
exit (EXIT_FAILURE);
case 0:
fprintf (stderr, "VBI read timeout\n");
exit (EXIT_FAILURE);
case 1: /* success */
break;
default:
assert (0);
}
n_lines = sliced_buffer->size / sizeof (vbi_sliced);
vbi_decode (dec,
(vbi_sliced *) sliced_buffer->data,
n_lines,
sliced_buffer->timestamp);
if (quit)
return;
}
printf ("No network ID received or network unknown.\n");
}
int
main (void)
{
char *errstr;
vbi_bool success;
setlocale (LC_ALL, "");
services = (VBI_SLICED_TELETEXT_B |
VBI_SLICED_VPS |
VBI_SLICED_CAPTION_525);
cap = vbi_capture_v4l2_new ("/dev/vbi",
/* buffers */ 5,
&services,
/* strict */ 0,
&errstr,
/* verbose */ FALSE);
if (NULL == cap) {
fprintf (stderr,
"Cannot capture VBI data with V4L2 interface:\n"
"%s\n",
errstr);
free (errstr);
exit (EXIT_FAILURE);
}
dec = vbi_decoder_new ();
assert (NULL != dec);
success = vbi_event_handler_add (dec,
(VBI_EVENT_NETWORK |
VBI_EVENT_NETWORK_ID),
handler,
/* user_data */ NULL);
assert (success);
mainloop ();
vbi_decoder_delete (dec);
vbi_capture_delete (cap);
exit (EXIT_SUCCESS);
}
vbi_locale_codeset
const char * vbi_locale_codeset(void)
Definition conv.c:1250
vbi_strndup_iconv
char * vbi_strndup_iconv(const char *dst_codeset, const char *src_codeset, const char *src, unsigned long src_size, int repl_char)
Definition conv.c:940
vbi_event_handler_add
vbi_bool vbi_event_handler_add(vbi_decoder *vbi, int event_mask, vbi_event_handler handler, void *user_data)
Definition vbi.c:188
vbi_decoder_new
vbi_decoder * vbi_decoder_new(void)
Allocate a new data service decoder instance.
Definition vbi.c:870
vbi_decode
void vbi_decode(vbi_decoder *vbi, vbi_sliced *sliced, int lines, double time)
Main function of the data service decoder.
Definition vbi.c:423
vbi_decoder_delete
void vbi_decoder_delete(vbi_decoder *vbi)
Delete a data service decoder instance.
Definition vbi.c:832
vbi_decoder
Definition vbi.h:48
vbi_event
Event union.
Definition event.h:736
vbi_network::cni_vps
int cni_vps
Definition event.h:106
vbi_network::cni_8302
int cni_8302
Definition event.h:126
vbi_network::cni_8301
int cni_8301
Definition event.h:117
vbi_network::call
signed char call[40]
Definition event.h:86
vbi_network::name
signed char name[64]
Definition event.h:80
vbi_sliced
This structure holds one scan line of sliced vbi data.
Definition sliced.h:320