root/trunk/libffado/tests/dumpiso_mod.cpp

Revision 962, 8.9 kB (checked in by ppalmers, 16 years ago)

apply patch of ticket #82

Line 
1 /*
2  * libraw1394 - library for raw access to the 1394 bus with the Linux subsystem.
3  *
4  * Copyright (C) 1999,2000 Andreas Bombe
5  *
6  * This library is licensed under the GNU Lesser General Public License (LGPL),
7  * version 2.1 or later. See the file COPYING.LIB in the distribution for
8  * details.
9  */
10  
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <getopt.h>
15 #include <errno.h>
16 #include <fcntl.h>
17
18 #include <libraw1394/raw1394.h>
19
20 #include "src/libieee1394/cycletimer.h"
21 #include "src/debugmodule/debugmodule.h"
22 #include "src/libstreaming/util/cip.h"
23 #include <netinet/in.h>
24
25 #define BUFFER 1000
26 #define PACKET_MAX 4096
27
28 u_int64_t listen_channels;
29 unsigned long which_port;
30 char *filename;
31 int file;
32 enum raw1394_iso_dma_recv_mode mode = RAW1394_DMA_DEFAULT;
33
34 DECLARE_GLOBAL_DEBUG_MODULE;
35
36 raw1394handle_t global_handle;
37
38 void usage_exit(int exitcode)
39 {
40         fprintf(stderr,
41 "Usage: dumpiso [opts] [FILE]\n"
42 "Dump IEEE 1394 isochronous channels to FILE or standard output.\n"
43 "\n"
44 "-c --channels  CHANNELS    Listen on these channels; CHANNELS is either a\n"
45 "                           number X or a range X-Y.\n"
46 "-p --port      PORT        Choose 1394 chip PORT. (default: 0)\n"
47 "-h --help                  Show this help.\n"
48 );
49
50         exit(exitcode);
51 }
52
53 void parse_args(int argc, char **argv)
54 {
55         char *tail;
56         unsigned long i, chan1, chan2;
57
58         int c;
59         int index;
60         static struct option opts[] = {
61                 { "channels", required_argument, NULL, 'c' },
62                 { "port",     required_argument, NULL, 'p' },
63                 { "help",     no_argument,       NULL, 'h' },
64                 { 0 }
65         };
66
67         while (1) {
68                 c = getopt_long(argc, argv, "hc:p:", opts, &index);
69                 if (c == -1) break;
70
71                 switch (c) {
72                 case 'c':
73                         chan1 = strtoul(optarg, &tail, 10);
74                         chan2 = chan1;
75
76                         if (*tail) {
77                                 if (tail[0] != '-' || !tail[1]) {
78                                         fprintf(stderr,
79                                                 "invalid argument to channels: %s\n",
80                                                 optarg);
81                                         usage_exit(1);
82                                 }
83
84                                 tail++;
85                                 chan2 = strtoul(tail, &tail, 10);
86                                 if (*tail) {
87                                         fprintf(stderr,
88                                                 "invalid argument to channels: %s\n",
89                                                 optarg);
90                                         usage_exit(1);
91                                 }
92                         } else {
93                                 mode = RAW1394_DMA_PACKET_PER_BUFFER;
94                         }
95
96                         if (chan2 < chan1) {
97                                 unsigned long x = chan1;
98                                 chan1 = chan2;
99                                 chan2 = x;
100                         }
101
102                         if (chan2 > 63) {
103                                 fprintf(stderr,
104                                         "invalid channel numbers: %s\n",
105                                         optarg);
106                                 exit(1);
107                         }
108
109                         for (i = chan1; i <= chan2; i++)
110                                 listen_channels |= 1ULL << i;
111
112                         break;
113                 case 'p':
114                         which_port = strtoul(optarg, &tail, 10);
115                         if (*tail) {
116                                 fprintf(stderr,
117                                         "invalid argument to port: %s\n",
118                                         optarg);
119                                 usage_exit(1);
120                         }
121                         break;
122                 case 'h':
123                         usage_exit(0);
124                 case '?':
125                         usage_exit(1);
126                 default:
127                         abort();
128                 }
129         }
130
131         argv += optind;
132         argc -= optind;
133
134         if (argc > 1) {
135                 fprintf(stderr, "Too many arguments.\n");
136                 usage_exit(1);
137         }
138
139         if (argc) filename = *argv;
140
141         if (!listen_channels) listen_channels = ~0ULL;
142 }
143
144 void write_header()
145 {
146         static char header[32] = "1394 isodump v3";
147         int i;
148
149         for (i = 0; i < 8; i++)
150                 header[i+16] = (listen_channels >> (56 - 8*i)) & 0xff;
151
152         i = 0;
153         while (i < 32) {
154                 int ret;
155                 ret = write(file, header + i, 32 - i);
156
157                 if (ret < 0) {
158                         perror("header write");
159                         exit(1);
160                 }
161
162                 i += ret;
163         }
164 }
165
166 void open_dumpfile()
167 {
168         if (!filename || !filename[0] || (filename[0] == '-' && !filename[1])) {
169                 file = fileno(stdout);
170                 write_header();
171                 return;
172         }
173
174         file = open(filename, O_CREAT | O_WRONLY, 0666);
175         if (file < 0) {
176                 perror("dumpfile open");
177                 exit(1);
178         }
179        
180         ftruncate(file, 0);
181         write_header();
182 }
183
184 static enum raw1394_iso_disposition
185 iso_handler(raw1394handle_t handle, unsigned char *data,
186         unsigned int length, unsigned char channel,
187         unsigned char tag, unsigned char sy, unsigned int cycle,
188         unsigned int dropped)
189 {
190         int ret;
191         static unsigned int counter = 0;
192         uint32_t cycle_timer;
193         uint64_t local_time;
194         struct iec61883_packet *packet = (struct iec61883_packet *) data;
195
196         if (++counter % 1000 == 0)
197                 fprintf(stderr, "\r%uK packets", counter/1000);
198        
199         raw1394_read_cycle_timer(global_handle, &cycle_timer, &local_time);
200        
201         uint32_t timestamp = 0;
202         bool ok = (packet->syt != 0xFFFF) &&
203                     (packet->fdf != 0xFF) &&
204                     (packet->fmt == 0x10) &&
205                     (packet->dbs > 0) &&
206                     (length >= 2*sizeof(quadlet_t));
207         if(ok) {
208             timestamp = sytRecvToFullTicks((uint32_t)ntohs(packet->syt),
209                                     cycle, cycle_timer);
210         }
211         /* write header */
212         unsigned short length2 = length;
213         unsigned short cycle2 = cycle;
214         write(file, &length2, sizeof(length2));
215         write(file, &cycle2, sizeof(cycle2));
216         write(file, &channel, sizeof(channel));
217         write(file, &cycle_timer, sizeof(cycle_timer));
218         write(file, &timestamp, sizeof(timestamp));
219         write(file, &tag, sizeof(tag));
220         write(file, &sy, sizeof(sy));
221         sy = 0;
222         write(file, &sy, sizeof(sy));
223
224         while (length) {
225                 ret = write(file, data, length);
226                 if (ret < 0) {
227                         perror("data write");
228                         return RAW1394_ISO_ERROR;
229                 }
230
231                 length -= ret;
232                 data += ret;
233         }
234
235         return RAW1394_ISO_OK;
236 }
237
238 int main(int argc, char **argv)
239 {
240         raw1394handle_t handle;
241         int i;
242
243         parse_args(argc, argv);
244
245         fprintf(stderr, "port: %ld\nchannels: %#016llx\nfile: %s\n", which_port,
246                 (long long unsigned int)(listen_channels), filename);
247
248         handle = raw1394_new_handle();
249         if (!handle) {
250                 if (!errno)
251                         fprintf(stderr,
252                                 "No working kernel driver found.\n");
253                 else
254                         perror("raw1394_get_handle");
255                 exit(1);
256         }
257
258         do {
259                 if ((unsigned long)(raw1394_get_port_info(handle, NULL, 0)) <= which_port) {
260                         fprintf(stderr, "Port %ld does not exist.\n",
261                                 which_port);
262                         exit(1);
263                 }
264
265                 raw1394_set_port(handle, which_port);
266         } while (errno == ESTALE);
267
268         if (errno) {
269                 perror("raw1394_set_port");
270                 exit(1);
271         }
272
273         global_handle = raw1394_new_handle();
274         raw1394_set_port(global_handle, which_port);
275
276         open_dumpfile();
277
278         if (mode == RAW1394_DMA_DEFAULT) {
279                 raw1394_iso_multichannel_recv_init(handle, iso_handler,
280                         BUFFER, 2048, -1); /* >2048 makes rawiso stall! */
281                 raw1394_iso_recv_set_channel_mask(handle, listen_channels);
282
283         } else for (i = 0; i < 64; i++) {
284                 if (!(listen_channels & 1ULL << i))
285                         continue;
286                 raw1394_iso_recv_init(handle, iso_handler, BUFFER, PACKET_MAX,
287                         i, mode, -1);
288         }
289         raw1394_iso_recv_start(handle, -1, -1, 0);
290
291         while (raw1394_loop_iterate(handle) == 0);
292
293         fprintf(stderr, "\n");
294         raw1394_iso_shutdown(handle);
295         raw1394_destroy_handle(handle);
296
297         return 0;
298 }
Note: See TracBrowser for help on using the browser.