root/trunk/libffado/tests/test-avccmd.cpp

Revision 1146, 6.9 kB (checked in by ppalmers, 13 years ago)

reset errno when parsing arguments. fixes #107.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2005-2008 by Daniel Wagner
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 2 of the License, or
13  * (at your option) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include <libraw1394/raw1394.h>
26 #include <libiec61883/iec61883.h>
27
28 #include "debugmodule/debugmodule.h"
29
30 #include "libieee1394/configrom.h"
31 #include "libieee1394/ieee1394service.h"
32 #include "libutil/cmd_serialize.h"
33 #include "libavc/general/avc_generic.h"
34
35 #include <argp.h>
36 #include <stdlib.h>
37 #include <iostream>
38
39 using namespace std;
40 using namespace AVC;
41 using namespace Util;
42
43 DECLARE_GLOBAL_DEBUG_MODULE;
44
45 #define MAX_ARGS 1000
46
47 class TestCmd: public AVCCommand
48 {
49 public:
50     TestCmd(Ieee1394Service& ieee1394service, opcode_t opcode );
51     virtual ~TestCmd();
52
53     virtual bool serialize( Util::Cmd::IOSSerialize& se );
54     virtual bool deserialize( Util::Cmd::IISDeserialize& de );
55
56     virtual const char* getCmdName() const
57     { return "TestCmd"; }
58    
59     byte_t args[MAX_ARGS];
60     int nargs;
61 };
62
63 ////////////////////////////////////////////////
64 // arg parsing
65 ////////////////////////////////////////////////
66 const char *argp_program_version = "test-avccmd 0.1";
67 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>";
68 static char doc[] = "test-avccmd -- test program to send a custom avc command to a specific node.";
69 static char args_doc[] = "NODE_ID [avc cmd byte sequence]";
70 static struct argp_option options[] = {
71     {"verbose",   'v', 0,           0,  "Produce verbose output" },
72     {"port",      'p', "PORT",      0,  "Set port" },
73     {"node",      'n', "NODE",      0,  "Set node" },
74    { 0 }
75 };
76
77 struct arguments
78 {
79     arguments()
80         : nargs ( 0 )
81         , verbose( false )
82         , test( false )
83         , port( 0 )
84         {
85             args[0] = 0;
86         }
87
88     char* args[MAX_ARGS];
89     int   nargs;
90     bool  verbose;
91     bool  test;
92     int   port;
93     int   node;
94 } arguments;
95
96 // Parse a single option.
97 static error_t
98 parse_opt( int key, char* arg, struct argp_state* state )
99 {
100     // Get the input argument from `argp_parse', which we
101     // know is a pointer to our arguments structure.
102     struct arguments* arguments = ( struct arguments* ) state->input;
103
104     char* tail;
105     errno = 0;
106     switch (key) {
107     case 'v':
108         arguments->verbose = true;
109         break;
110     case 't':
111         arguments->test = true;
112         break;
113     case 'p':
114         arguments->port = strtol(arg, &tail, 0);
115         if (errno) {
116             perror("argument parsing failed:");
117             return errno;
118         }
119         break;
120     case 'n':
121         arguments->node = strtol(arg, &tail, 0);
122         if (errno) {
123             perror("argument parsing failed:");
124             return errno;
125         }
126         break;
127     case ARGP_KEY_ARG:
128         if (state->arg_num >= MAX_ARGS) {
129             // Too many arguments.
130             argp_usage (state);
131         }
132         arguments->args[state->arg_num] = arg;
133         arguments->nargs++;
134         break;
135     case ARGP_KEY_END:
136         if(arguments->nargs<4) {
137             printf("not enough arguments\n");
138             return -1;
139         }
140        
141         break;
142     default:
143         return ARGP_ERR_UNKNOWN;
144     }
145     return 0;
146 }
147
148 static struct argp argp = { options, parse_opt, args_doc, doc };
149
150 ///////////////////////////
151 // main
152 //////////////////////////
153 int
154 main(int argc, char **argv)
155 {
156     // arg parsing
157     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
158         fprintf( stderr, "Could not parse command line\n" );
159         exit(-1);
160     }
161     errno = 0;
162     char* tail;
163
164
165     Ieee1394Service *m_1394Service = new Ieee1394Service();
166     if ( !m_1394Service ) {
167         debugFatal( "Could not create Ieee1349Service object\n" );
168         return false;
169     }
170
171     if ( !m_1394Service->initialize( arguments.port ) ) {
172         debugFatal( "Could not initialize Ieee1349Service object\n" );
173         delete m_1394Service;
174         m_1394Service = 0;
175         return false;
176     }
177
178     char cmdtype = strtol(arguments.args[0], &tail, 0);
179     if (errno) {
180         perror("argument parsing failed:");
181         return -1;
182     }
183     char unit_subunit = strtol(arguments.args[1], &tail, 0);
184     if (errno) {
185         perror("argument parsing failed:");
186         return -1;
187     }
188     opcode_t opcode = strtol(arguments.args[2], &tail, 0);
189     if (errno) {
190         perror("argument parsing failed:");
191         return -1;
192     }
193    
194     TestCmd cmd( *m_1394Service, opcode );
195     switch (cmdtype) {
196         case AVC::AVCCommand::eCT_Control: cmd.setCommandType( AVC::AVCCommand::eCT_Control ); break;
197         case AVC::AVCCommand::eCT_Status: cmd.setCommandType( AVC::AVCCommand::eCT_Status ); break;
198         case AVC::AVCCommand::eCT_SpecificInquiry: cmd.setCommandType( AVC::AVCCommand::eCT_SpecificInquiry ); break;
199         case AVC::AVCCommand::eCT_Notify: cmd.setCommandType( AVC::AVCCommand::eCT_Notify ); break;
200         case AVC::AVCCommand::eCT_GeneralInquiry: cmd.setCommandType( AVC::AVCCommand::eCT_GeneralInquiry ); break;
201         default: printf("Invalid command type: 0x%02X.\n", cmdtype); exit(-1);
202     }
203     cmd.setNodeId( arguments.node );
204    
205     cmd.setSubunitType( byteToSubunitType(unit_subunit >> 3) );
206     cmd.setSubunitId( (unit_subunit & 0x7) );
207    
208     cmd.setVerbose( DEBUG_LEVEL_VERY_VERBOSE );
209    
210     int i=0;
211
212     for (;i<arguments.nargs-3;i++) {
213         char tmp = strtol(arguments.args[i+3], &tail, 0);
214         if (errno) {
215             perror("argument parsing failed:");
216             break;
217         }
218         cmd.args[i]=tmp;
219     }
220
221     cmd.nargs=i;
222
223     if ( !cmd.fire() ) {
224         debugError( "TestCmd info command failed\n" );
225         return 0;
226     }
227
228     delete m_1394Service;
229
230     return 0;
231 }
232
233 TestCmd::TestCmd(Ieee1394Service& ieee1394service, opcode_t opcode )
234     : AVCCommand( ieee1394service, opcode )
235 {
236 }
237
238 TestCmd::~TestCmd()
239 {
240 }
241
242 bool
243 TestCmd::serialize( Util::Cmd::IOSSerialize& se )
244 {
245     bool result=true;
246     result &= AVCCommand::serialize( se );
247     for (int i=0;i<nargs;i++) {
248         byte_t byte=args[i];
249         result &= se.write(byte, "arg");
250     }
251     return result;
252 }
253
254 bool
255 TestCmd::deserialize( Util::Cmd::IISDeserialize& de )
256 {
257     bool result=true;
258     result &= AVCCommand::deserialize( de );
259    
260     bool tmpresult=true;
261     nargs=0;
262     while(tmpresult=de.read(&args[nargs])) {
263         nargs++;
264     }
265    
266     return result;
267 }
268
Note: See TracBrowser for help on using the browser.