root/branches/libffado-2.0/tests/systemtests/test-isorecv-1.cpp

Revision 1146, 7.2 kB (checked in by ppalmers, 16 years ago)

reset errno when parsing arguments. fixes #107.

Line 
1 /*
2  * Parts Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /*
25  * based on howdyget.c (unknown source, maybe Maas Digital LLC)
26  */
27
28 #include <libraw1394/raw1394.h>
29 #include <stdio.h>
30 #include <errno.h>
31 #include <unistd.h>
32
33 #include <argp.h>
34
35 #include "debugmodule/debugmodule.h"
36 #include "realtimetools.h"
37
38 uint32_t count = 0;
39
40 DECLARE_GLOBAL_DEBUG_MODULE;
41
42 #define MAX_EXTRA_ARGS 2
43 // Program documentation.
44 // Program documentation.
45 static char doc[] = "FFADO -- ISO receive test\n\n";
46
47 // A description of the arguments we accept.
48 static char args_doc[] = "";
49
50 struct arguments
51 {
52     long int verbose;
53     long int port;
54     long int channel;
55     long int packetsize;
56     long int buffersize;
57     long int interval;
58     long int countdown;
59     long int startoncycle;
60     long int printinterval;
61     long int rtprio;
62     char* args[MAX_EXTRA_ARGS];
63 };
64
65 // The options we understand.
66 static struct argp_option options[] = {
67     {"verbose",  'v', "level",    0,  "Verbose level" },
68     {"port",  'p', "port",  0,  "firewire port to use" },
69     {"channel",  'c', "channel",  0,  "iso channel to use" },
70     {"packetsize",  's', "packetsize",  0,  "packet size to use" },
71     {"buffersize",  'b', "buffersize",  0,  "number of packets to buffer" },
72     {"interval",  'i', "interval",  0,  "interrupt interval in packets" },
73     {"startoncycle",  't', "cycle",  0,  "start on a specific cycle" },
74      {"countdown",  'u', "count",  0,  "number of iterations to run" },
75     {"printinterval",  'r', "packets",  0,  "number of packets between successive status prints" },
76     {"rtprio",  'P', "prio",  0,  "real time priority of the iterator process/thread (0 = no RT)" },
77     { 0 }
78 };
79
80 // Parse a single option.
81 #define PARSE_ARG_LONG(XXletterXX, XXvarXX, XXdescXX) \
82     case XXletterXX: \
83         if (arg) { \
84             XXvarXX = strtol( arg, &tail, 0 ); \
85             if ( errno ) { \
86                 fprintf( stderr,  "Could not parse '%s' argument\n", XXdescXX ); \
87                 return ARGP_ERR_UNKNOWN; \
88             } \
89         } \
90         break;
91
92 static error_t
93 parse_opt( int key, char* arg, struct argp_state* state )
94 {
95     // Get the input argument from `argp_parse', which we
96     // know is a pointer to our arguments structure.
97     struct arguments* arguments = ( struct arguments* ) state->input;
98     char* tail;
99
100     errno = 0;
101     switch (key) {
102     PARSE_ARG_LONG('v', arguments->verbose, "verbose");
103     PARSE_ARG_LONG('p', arguments->port, "port");
104     PARSE_ARG_LONG('c', arguments->channel, "channel");
105     PARSE_ARG_LONG('s', arguments->packetsize, "packetsize");
106     PARSE_ARG_LONG('b', arguments->buffersize, "buffersize");
107     PARSE_ARG_LONG('i', arguments->interval, "interval");
108     PARSE_ARG_LONG('u', arguments->countdown, "countdown");
109     PARSE_ARG_LONG('r', arguments->printinterval, "printinterval");
110     PARSE_ARG_LONG('t', arguments->startoncycle, "startoncycle");
111     PARSE_ARG_LONG('P', arguments->rtprio, "rtprio");
112
113     case ARGP_KEY_ARG:
114         break;
115     case ARGP_KEY_END:
116         break;
117     default:
118         return ARGP_ERR_UNKNOWN;
119     }
120     return 0;
121 }
122
123 // Our argp parser.
124 static struct argp argp = { options, parse_opt, args_doc, doc };
125
126 // the global arguments struct
127 struct arguments arguments;
128
129 int last_cycle = -1;
130
131 static enum raw1394_iso_disposition myISOGetter(raw1394handle_t handle,
132         unsigned char *data,
133         unsigned int len,
134         unsigned char channel,
135         unsigned char tag,
136         unsigned char sy,
137         unsigned int cycle,
138         unsigned int dropped1)
139 {
140     unsigned int skipped = (dropped1 & 0xFFFF0000) >> 16;
141     unsigned int dropped = dropped1 & 0xFFFF;
142
143     //debugOutput(DEBUG_LEVEL_INFO, "In handler\n");
144     //sprintf((char *)data, "Hello World %8u\n", count);
145     if (last_cycle >= 0) {
146         if (cycle != ((unsigned int)last_cycle + 1) % 8000) {
147             debugOutput(DEBUG_LEVEL_INFO, "nonmonotonic cycles: this: %04d, last: %04d, dropped: 0x%08X\n", cycle, last_cycle, dropped1);
148         }
149     }
150     last_cycle = cycle;
151     count++;
152     if(dropped) debugOutput(DEBUG_LEVEL_INFO, "Dropped packets! (%d)\n", dropped);
153     if(skipped) debugOutput(DEBUG_LEVEL_INFO, "Skipped packets! (%d)\n", skipped);
154     if (count % arguments.printinterval == 0) debugOutput(DEBUG_LEVEL_INFO, "cycle=%d count=%d\n", cycle, count);
155     return RAW1394_ISO_OK;
156 }
157
158 int main(int argc, char **argv)
159 {
160     raw1394handle_t handle;
161
162     // Default values.
163     arguments.verbose = DEBUG_LEVEL_VERBOSE;
164     arguments.port = 0;
165     arguments.channel = 0;
166     arguments.packetsize = 1024;
167     arguments.buffersize = 100;
168     arguments.interval = -1;
169     arguments.startoncycle = -1;
170     arguments.countdown = 10000;
171     arguments.printinterval = 100;
172     arguments.rtprio = 0;
173
174     // Parse our arguments; every option seen by `parse_opt' will
175     // be reflected in `arguments'.
176     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
177         debugError("Could not parse command line\n" );
178         return -1;
179     }
180
181     debugOutput(DEBUG_LEVEL_INFO, "Get 1394 handle...\n");
182     handle = raw1394_new_handle();
183     if(!handle)
184     {
185         perror("raw1394_new_handle");
186         return -1;
187     }
188
189     debugOutput(DEBUG_LEVEL_INFO, "Select 1394 port %d...\n", arguments.port);
190     do
191     {
192         if (raw1394_get_port_info(handle, NULL, 0) < 0)
193         {
194             perror("raw1394_get_port_info");
195             return 1;
196         }
197         raw1394_set_port(handle, arguments.port);
198     } while (errno == ESTALE);
199
200     if(errno)
201     {
202         perror("raw1394_set_port");
203         return 1;
204     }
205
206     debugOutput(DEBUG_LEVEL_INFO, "Init ISO receive...\n");
207     if(raw1394_iso_recv_init(handle,
208                 myISOGetter,
209                 arguments.buffersize,
210                 arguments.packetsize,
211                 arguments.channel,
212                 RAW1394_DMA_DEFAULT,
213                 arguments.interval))
214     {
215         perror("raw1394_iso_recv_init");
216         return 1;
217     }
218
219     debugOutput(DEBUG_LEVEL_INFO, "Start ISO receive...\n");
220     if(raw1394_iso_recv_start(handle, arguments.startoncycle, 0xF, 0))
221     {
222         perror("raw1394_iso_recv_start");
223         return 1;
224     }
225
226     debugOutput(DEBUG_LEVEL_INFO, "Setting RT priority (%d)...\n", arguments.rtprio);
227     set_realtime_priority(arguments.rtprio);
228
229     debugOutput(DEBUG_LEVEL_INFO, "Starting iterate loop...\n");
230     int countdown = arguments.countdown;
231     while(countdown--)
232     {
233         if(raw1394_loop_iterate(handle))
234         {
235             perror("raw1394_loop_iterate");
236             return 1;
237         }
238     }
239     return 0;
240 }
Note: See TracBrowser for help on using the browser.