root/trunk/libffado/tests/dumpiso_mod.cpp

Revision 1134, 9.2 kB (checked in by ppalmers, 16 years ago)

revert r1131 since it's does unconditional byteswapping

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