Bug Summary

File:asi.c
Location:line 267, column 14
Description:Branch condition evaluates to a garbage value

Annotated Source Code

1/*****************************************************************************
2 * asi.c: support for Computer Modules ASI cards
3 *****************************************************************************
4 * Copyright (C) 2004, 2009 VideoLAN
5 *
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
22#include "config.h"
23
24#ifdef HAVE_ASI_SUPPORT
25
26#include <stdlib.h>
27#include <stdio.h>
28#include <unistd.h>
29#include <stdint.h>
30#include <stdbool.h>
31#include <string.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <fcntl.h>
35#include <sys/uio.h>
36#include <sys/poll.h>
37#include <sys/ioctl.h>
38#include <sys/socket.h>
39#include <netinet/in.h>
40#include <arpa/inet.h>
41#include <errno(*__errno_location ()).h>
42
43#include <bitstream/common.h>
44
45#include "asi.h"
46
47#include "dvblast.h"
48
49/*
50 * The problem with hardware filtering is that on startup, when you only
51 * set a filter on PID 0, it can take a very long time for a large buffer
52 * (typically ~100 TS packets) to fill up. And the buffer size cannot be
53 * adjusted afer startup. --Meuuh
54 */
55//#define USE_HARDWARE_FILTERING
56
57/*****************************************************************************
58 * Local declarations
59 *****************************************************************************/
60#define ASI_DEVICE"/dev/asirx%u" "/dev/asirx%u"
61#define ASI_TIMESTAMPS_FILE"/sys/class/asi/asirx%u/timestamps" "/sys/class/asi/asirx%u/timestamps"
62#define ASI_BUFSIZE_FILE"/sys/class/asi/asirx%u/bufsize" "/sys/class/asi/asirx%u/bufsize"
63#define ASI_LOCK_TIMEOUT5000000 5000000 /* 5 s */
64
65static int i_handle;
66static int i_bufsize;
67static uint8_t p_pid_filter[8192 / 8];
68static mtime_t i_last_packet = 0;
69
70/*****************************************************************************
71 * Local helpers
72 *****************************************************************************/
73#define MAXLEN256 256
74
75static int ReadULSysfs( const char *psz_fmt, unsigned int i_link )
76{
77 char psz_file[MAXLEN256], psz_data[MAXLEN256];
78 char *psz_tmp;
79 int i_fd;
80 ssize_t i_ret;
81 unsigned int i_data;
82
83 snprintf( psz_file, sizeof(psz_file), psz_fmt, i_link );
84 psz_file[sizeof(psz_file) - 1] = '\0';
85
86 if ( (i_fd = open( psz_file, O_RDONLY00 )) < 0 )
87 return i_fd;
88
89 i_ret = read( i_fd, psz_data, sizeof(psz_data) );
90 close( i_fd );
91
92 if ( i_ret < 0 )
93 return i_ret;
94
95 i_data = strtoul( psz_data, &psz_tmp, 0 );
96 if ( *psz_tmp != '\n' )
97 return -1;
98
99 return i_data;
100}
101
102static ssize_t WriteULSysfs( const char *psz_fmt, unsigned int i_link,
103 unsigned int i_buf )
104{
105 char psz_file[MAXLEN256], psz_data[MAXLEN256];
106 int i_fd;
107 ssize_t i_ret;
108
109 snprintf( psz_file, sizeof(psz_file), psz_fmt, i_link );
110 psz_file[sizeof(psz_file) - 1] = '\0';
111
112 snprintf( psz_data, sizeof(psz_data), "%u\n", i_buf );
113 psz_file[sizeof(psz_data) - 1] = '\0';
114
115 if ( (i_fd = open( psz_file, O_WRONLY01 )) < 0 )
116 return i_fd;
117
118 i_ret = write( i_fd, psz_data, strlen(psz_data) + 1 );
119 close( i_fd );
120 return i_ret;
121}
122
123/*****************************************************************************
124 * asi_Open
125 *****************************************************************************/
126void asi_Open( void )
127{
128 char psz_dev[MAXLEN256];
129
130 /* No timestamp - we wouldn't know what to do with them */
131 if ( WriteULSysfs( ASI_TIMESTAMPS_FILE"/sys/class/asi/asirx%u/timestamps", i_asi_adapter, 0 ) < 0 )
132 {
133 msg_Err( NULL((void*)0), "couldn't write file " ASI_TIMESTAMPS_FILE"/sys/class/asi/asirx%u/timestamps",
134 i_asi_adapter );
135 exit(EXIT_FAILURE1);
136 }
137
138 if ( (i_bufsize = ReadULSysfs( ASI_BUFSIZE_FILE"/sys/class/asi/asirx%u/bufsize", i_asi_adapter )) < 0 )
139 {
140 msg_Err( NULL((void*)0), "couldn't read file " ASI_BUFSIZE_FILE"/sys/class/asi/asirx%u/bufsize", i_asi_adapter );
141 exit(EXIT_FAILURE1);
142 }
143
144 if ( i_bufsize % TS_SIZE188 )
145 {
146 msg_Err( NULL((void*)0), ASI_BUFSIZE_FILE"/sys/class/asi/asirx%u/bufsize" " must be a multiple of 188",
147 i_asi_adapter );
148 exit(EXIT_FAILURE1);
149 }
150
151 snprintf( psz_dev, sizeof(psz_dev), ASI_DEVICE"/dev/asirx%u", i_asi_adapter );
152 psz_dev[sizeof(psz_dev) - 1] = '\0';
153 if ( (i_handle = open( psz_dev, O_RDONLY00, 0 )) < 0 )
154 {
155 msg_Err( NULL((void*)0), "couldn't open device " ASI_DEVICE"/dev/asirx%u" " (%s)",
156 i_asi_adapter, strerror(errno(*__errno_location ())) );
157 exit(EXIT_FAILURE1);
158 }
159
160#ifdef USE_HARDWARE_FILTERING
161 memset( p_pid_filter, 0x0, sizeof(p_pid_filter) );
162#else
163 memset( p_pid_filter, 0xff, sizeof(p_pid_filter) );
164 p_pid_filter[8191 / 8] &= ~(0x01 << (8191 % 8)); /* padding */
165#endif
166 if ( ioctl( i_handle, ASI_IOC_RXSETPF(((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) |
(((76)) << 0) | ((((sizeof(unsigned int [256])))) <<
((0 +8)+8)))
, p_pid_filter ) < 0 )
167 {
168 msg_Warn( NULL((void*)0), "couldn't filter padding" );
169 }
170
171 fsync( i_handle );
172}
173
174/*****************************************************************************
175 * asi_Read : read packets from the device
176 *****************************************************************************/
177block_t *asi_Read( mtime_t i_poll_timeout )
178{
179 struct pollfd pfd[2];
180 int i_ret, i_nb_fd = 1;
181
182 pfd[0].fd = i_handle;
183 pfd[0].events = POLLIN0x001;
184 if ( i_comm_fd != -1 )
1
Taking false branch
185 {
186 pfd[1].fd = i_comm_fd;
187 pfd[1].events = POLLIN0x001;
188 i_nb_fd++;
189 }
190
191 i_ret = poll( pfd, i_nb_fd, (i_poll_timeout + 999) / 1000 );
192
193 i_wallclock = mdate();
194
195 if ( i_ret < 0 )
2
Assuming 'i_ret' is >= 0
3
Taking false branch
196 {
197 if( errno(*__errno_location ()) != EINTR4 )
198 msg_Err( NULL((void*)0), "couldn't poll from device " ASI_DEVICE"/dev/asirx%u" " (%s)",
199 i_asi_adapter, strerror(errno(*__errno_location ())) );
200 return NULL((void*)0);
201 }
202
203 if ( (pfd[0].revents & POLLPRI0x002) )
4
Taking false branch
204 {
205 unsigned int i_val;
206
207 if ( ioctl(i_handle, ASI_IOC_RXGETEVENTS(((2U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) |
(((66)) << 0) | ((((sizeof(unsigned int)))) << (
(0 +8)+8)))
, &i_val) < 0 )
208 msg_Err( NULL((void*)0), "couldn't RXGETEVENTS (%s)", strerror(errno(*__errno_location ())) );
209 else
210 {
211 if ( i_val & ASI_EVENT_RX_BUFFER(1 << 0) )
212 msg_Warn( NULL((void*)0), "driver receive buffer queue overrun" );
213 if ( i_val & ASI_EVENT_RX_FIFO(1 << 1) )
214 msg_Warn( NULL((void*)0), "onboard receive FIFO overrun" );
215 if ( i_val & ASI_EVENT_RX_CARRIER(1 << 2) )
216 msg_Warn( NULL((void*)0), "carrier status change" );
217 if ( i_val & ASI_EVENT_RX_LOS(1 << 4) )
218 msg_Warn( NULL((void*)0), "loss of packet synchronization" );
219 if ( i_val & ASI_EVENT_RX_AOS(1 << 3) )
220 msg_Warn( NULL((void*)0), "acquisition of packet synchronization" );
221 if ( i_val & ASI_EVENT_RX_DATA(1 << 5) )
222 msg_Warn( NULL((void*)0), "receive data status change" );
223 }
224 }
225
226 if ( (pfd[0].revents & POLLIN0x001) )
5
Taking true branch
227 {
228 struct iovec p_iov[i_bufsize / TS_SIZE188];
229 block_t *p_ts, **pp_current = &p_ts;
230 int i, i_len;
231
232 if ( !i_last_packet )
6
Assuming 'i_last_packet' is not equal to 0
7
Taking false branch
233 {
234 switch (i_print_type) {
235 case PRINT_XML:
236 printf("<STATUS type=\"lock\" status=\"1\"/>\n");
237 break;
238 default:
239 printf("frontend has acquired lock\n" );
240 }
241 }
242 i_last_packet = i_wallclock;
243
244 for ( i = 0; i < i_bufsize / TS_SIZE188; i++ )
8
Loop condition is false. Execution continues on line 252
245 {
246 *pp_current = block_New();
247 p_iov[i].iov_base = (*pp_current)->p_ts;
248 p_iov[i].iov_len = TS_SIZE188;
249 pp_current = &(*pp_current)->p_next;
250 }
251
252 if ( (i_len = readv(i_handle, p_iov, i_bufsize / TS_SIZE188)) < 0 )
9
Taking false branch
253 {
254 msg_Err( NULL((void*)0), "couldn't read from device " ASI_DEVICE"/dev/asirx%u" " (%s)",
255 i_asi_adapter, strerror(errno(*__errno_location ())) );
256 i_len = 0;
257 }
258 i_len /= TS_SIZE188;
259
260 pp_current = &p_ts;
261 while ( i_len && *pp_current )
262 {
263 pp_current = &(*pp_current)->p_next;
264 i_len--;
265 }
266
267 if ( *pp_current )
10
Branch condition evaluates to a garbage value
268 msg_Dbg( NULL((void*)0), "partial buffer received" );
269 block_DeleteChain( *pp_current );
270 *pp_current = NULL((void*)0);
271
272 return p_ts;
273 }
274 else if ( i_last_packet && i_last_packet + ASI_LOCK_TIMEOUT5000000 < i_wallclock )
275 {
276 switch (i_print_type) {
277 case PRINT_XML:
278 printf("<STATUS type=\"lock\" status=\"0\"/>\n");
279 break;
280 default:
281 printf("frontend has lost lock\n" );
282 }
283 i_last_packet = 0;
284 }
285
286 if ( i_comm_fd != -1 && pfd[1].revents )
287 comm_Read();
288
289 return NULL((void*)0);
290}
291
292/*****************************************************************************
293 * asi_SetFilter
294 *****************************************************************************/
295int asi_SetFilter( uint16_t i_pid )
296{
297#ifdef USE_HARDWARE_FILTERING
298 p_pid_filter[ i_pid / 8 ] |= (0x01 << (i_pid % 8));
299 if ( ioctl( i_handle, ASI_IOC_RXSETPF(((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) |
(((76)) << 0) | ((((sizeof(unsigned int [256])))) <<
((0 +8)+8)))
, p_pid_filter ) < 0 )
300 msg_Warn( NULL((void*)0), "couldn't add filter on PID %u", i_pid );
301
302 return 1;
303#else
304 return -1;
305#endif
306}
307
308/*****************************************************************************
309 * asi_UnsetFilter: normally never called
310 *****************************************************************************/
311void asi_UnsetFilter( int i_fd, uint16_t i_pid )
312{
313#ifdef USE_HARDWARE_FILTERING
314 p_pid_filter[ i_pid / 8 ] &= ~(0x01 << (i_pid % 8));
315 if ( ioctl( i_handle, ASI_IOC_RXSETPF(((1U) << (((0 +8)+8)+14)) | ((('?')) << (0 +8)) |
(((76)) << 0) | ((((sizeof(unsigned int [256])))) <<
((0 +8)+8)))
, p_pid_filter ) < 0 )
316 msg_Warn( NULL((void*)0), "couldn't remove filter on PID %u", i_pid );
317#endif
318}
319
320/*****************************************************************************
321 * asi_Reset
322 *****************************************************************************/
323void asi_Reset( void )
324{
325 msg_Warn( NULL((void*)0), "asi_Reset() do nothing" );
326}
327
328#endif